2.9.16.0
Coherent GT for UE4
FAQ

How to seamlessly travel between levels with Coherent GT enabled?

You need to make a few changes to your code to use seamless travelling with Coherent GT.

  1. All the Coherent GT components that you'd like to preserve to the next level must have their parent actors added to the list of travelling actors.
  2. The unique instance of Coherent GT's ACoherentUIGTSystem must also be added to the same list.

The above steps can be achieved by overriding APlayerController::GetSeamlessTravelActorList in your player controller implementation using the following code (assuming that all objects containing Coherent GT components are tagged with "PreserveCoherentGT"):

void AMyPlayerController::GetSeamlessTravelActorList(bool bToEntry, TArray<AActor*>& ActorList)
{
    // Add the actors containing Coherent GT components
    for (TActorIterator<AActor> It(GetWorld()); It; ++It)
    {
        if (It->Tags.Contains("PreserveCoherentGT"))
        {
            ActorList.Add(*It);
            break;
        }
    }
    // Add the unique instance of ACoherentUIGTSystem
    for (TActorIterator<ACoherentUIGTSystem> It(GetWorld()); It; ++It)
    {
        ActorList.Add(*It);
        break;
    }
}

Finally, make sure that no ACoherentUIGTSystem actor exists in the target level. If this is not the case, the old system and the new one will clash and your views will experience weird behaviour (such as time passing by faster than it should).

Can I use a gamepad to control my UI?

Certainly! Coherent GT uses UE4's gamepad data to expose the HTML5 Gamepad API. You don't have to do anything on game side to enable the gamepad input, simply connect your controller, focus a Coherent GT View or UMG widget and you're good to go. See the Gamepad_Map for a sample that utilises this functionality.

There are many ways one can bind the gamepad's buttons and axes. Coherent GT uses the standard gamepad mapping as described by the W3C here.

Important note: the HTML5 gamepad API uses polling instead of events (which the keyboard and mouse use). Due to this, it is mandatory that the state of all gamepads is updated on all views - even those that are not focused. If you have multiple conflicting views reading the gamepad state at the same time, you'll need to use JavaScript to control which view should listen for gamepad inputs.

What happens with the gamepad when the focus returns from the UI back to the game?

The system will set to zero all buttons and axes by default. This prevents the case in which a pressed button will continue to be pressed in the UI while the focus is still in the game. However, you can change the gamepad behaviour by calling ACoherentUIGTInputActor::GetGamepadBehaviourDelegate() which will return a delegate you can bind your callback to. For example

auto MyFunc = [](uint32 UserIf) -> EGamepadFocusLostBehaviour
{
    return EGamepadFocusLostBehaviour::ResetState;
}
InputActor->ACoherentUIGTInputActor::GetGamepadBehaviourDelegate().BindLambda(MyFunc);

Your function has to return one of these values: EGamepadFocusLostBehaviour::ResetState - Set the current state to zero. This is default behaviour. EGamepadFocusLostBehaviour::UseCurrentState - Will keep the last known state. Note that this will trigger the behaviour mentioned above. EGamepadFocusLostBehaviour::StateBeforeReset - Will save the last known state, set the current state to zero and once focus is regained by UI that saved state will be reapplied

Note: You cannot bind your function to the delegate from Blueprints, you must use C++.

How do I localize my game?

  1. Follow UE4's localization tutorial to setup the required translations.
  2. Inside the UE4 editor, go to Coherent GT -> Options and check Enable Localization.
  3. For any element you need localized add the data-l10n-id attribute and pass the namespace and key of the translated FText e.g:
    <button data-l10n-id='MyNamespace.MyTextKey'></button>
    

See the Localization Tutorial for a detailed walkthrough.

How do I use GT for a loading screen?

Follow the steps outline in Building a Loading Screen.

Building for Linux

UE4 supports cross-compilation to Linux. The process is straight-forward and is well-described in the UE4 wiki: https://wiki.unrealengine.com/Compiling_For_Linux

Starting from version 1.8, Coherent GT supports Linux and does not require anything specific to build the game. As on other platforms, you must copy the native Coherent GT and Renoir shared libraries next to the game's executable or in Engine/Binaries/ThirdParty/CoherentUIGT/Linux and Engine/Binaries/ThirdParty/Renoir/Linux respectively.

Building a UE4 dedicated server

To build a dedicated server for your game, you have to setup a Server Target. You can check the CoUIGTTestFPSServer.Target.cs file located in our sample game CoUIGTTestFPS/Source/CoUIGTTestFPSServer.Target.cs

You can check the whole procedure of Cooking the data for your server and building it here: https://wiki.unrealengine.com/Standalone_Dedicated_Server

Can I share textures between the game and the UI?

Sure! This can reduce memory consumption and improve startup time but you'll first have to tell us what images are shared. See the preloaded section for explanation about how to set them up.

Our UI uses a lot of fonts, can I tell to Coherent GT to load them all, without using `@font-face`?

Yes, any font placed in */Game/Content/Fonts* will be automatically loaded when the game starts. Please note that Coherent GT requires the raw .ttf and .otf files (not the .uasset files that UE4 will generate for them). This means that in order to get your fonts packaged, you'd have to add the Fonts directory under Edit –> Project Settings –> Packaging –> Additional directories to always package.

Any font loaded this way will be available immediately after the game starts to be used as a font-family.

My game doesn't cover the entire screen but I'd like my HUD to do so. How do I do that?

If you are using letterboxing or your game is running on a platform with a constrained safe zone you HUD will be scaled appropriately. However, you might desire the HUD go over game's boundaries and this is possible by checking off the Respect Safe Zone and Respect Letterboxing settings found under Coherent GT -> Options in the UE4 editor. This will cause the HUD to disregard the boundaries. To understand how these properties interact with each other see the following graphic:

safezone_letterboxing_interactions.png
Safe zone & Letterboxing

By default Coherent GT will respect both the safe area and letterboxing boundaries.

How do I keep the UI running while the game is paused?

Simply go to Coherent GT –> Options and check Tick While Game Is Paused

A part of my UI seems to be a couple frames behind the game. What is happening and how do I fix it?

This might happen if something in your UI depends on actor/world updates and must be perfectly in sync to look right. The reason this happens is because our component ticks during TG_StartPhysics and any bindings are sent during TG_DuringPhysics, but cameras are updated between TG_PostPhysics and TG_PostUpdateWork. We've added an option to delay the component's ticks to TG_PostUpdateWork and after any bindings are sent, which makes it so the UI receives the updated bindings before drawing. To enable the option, either enable it from the Editor (click on your GT component and tick Delayed Update) or enable it using SetupUIGTView (the bDelayedUpdate argument - false by default). Alternatively, you can use EnableDelayedUpdate(true) on the component - available in both blueprints and C++.

Note
This option should only be used if absolutely necessary - when a visual effect in the UI has to be perfectly in sync with something in the game world (i.e. nameplates above actors). It could have a negative impact on performance depending on the circumstances, so use with care.
Warning
This option does not work on data sent via blueprints. To enable the effect for BP code, you must add a Set Tick Group node to the BeginPlay event in the blueprint with self as the target and Post Update Work as the tick group (in addition to enabling the option). This is needed, because blueprints tick during StartPhysics by default, which is before the cameras are updated and you will be sending old data (from the previous tick).

How to automatically use GPU-compressed images instead of other formats?

Imagine that you have the following case:

<img src="foo.png"></img>

Then, in order to save memory and decoding time, you may want GT to automatically load a matching DDS file if one exists.

GT doesn't support automatic fallback to DDS images when they are available but you can achieve it by slightly modifying the plugin following two steps:

  1. For each PNG file add DDS variant with the suffix *_compressed*. For example, if you have image "foo.png" you need to add "foo_compressed.dds" one in the same folder.
  2. Replace the void FCoherentUIGTFileHandler::ReadResource function's body in the CoherentUIGTFileHandler.cpp with the following code:
FString ResourcePathNonConst = ResourcePath;
if (TryUsePreloadedResource(ResourcePathNonConst, Response))
{
return;
}
if (ResourcePathNonConst.Contains(TEXT(".png")))
{
FString ResourcePathDds = ResourcePathNonConst.Replace(TEXT(".png"), TEXT("_compressed.dds"));
auto& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
if (PlatformFile.FileExists(*ResourcePathDds))
ResourcePathNonConst = ResourcePathDds;
}
int64 Start = 0;
int64 End = 0;
bool bIsRangeRequest = IsRangeRequest(Start, End, Request);
TArray<uint8> Buffer;
int64 FileSize = 0;
if (!TryReadFile(ResourcePathNonConst, Start, End, bIsRangeRequest, Buffer, FileSize))
{
UE_LOG(LogCoherentUIGT, Error, TEXT("Could not read file '%s'."), *ResourcePathNonConst);
Response->SignalFailure();
Response->Release();
return;
}
SetResponseHeaders(FileSize, Buffer.Num(), Start, bIsRangeRequest, Response);
Response->ReceiveData((const char*)Buffer.GetData(), Buffer.Num());
Response->SignalSuccess();
Response->Release();

Saving Debug Render Frames

You can use DebugSaveNextFrame and BeginDebugFrameSave methods on GT components/UMG widget which will capture rendering frames and save them to files in GameDir/Saved/CoherentUIGT/ folder. This can be useful when debugging rendering related issues.

As of now, these files can only be inspected by our own internal tools and you can't inspect them yourself. However, in the case of a graphics artefact, you can send them to our support team for investigation.

Note this is only for debugging and it has performance implications when used.

  • DebugSaveNextFrame forces a redraw on the whole UI.
  • BeginDebugFrameSave Starts saving every frame without forcing redraw and actually saving only the changed parts of the UI.

Is it possible for the UI to be painted directly into the backbuffer of the game instead of in another texture ?

The PaintToBackBuffer option in the HUD settings of the Coherent GT plugin allows you to paint directly into the backbuffer of the game. In order to enable this option run the UE4 editor, go to Coherent GT -> Options and under the HUD section check Paint to Back Buffer.

This option improves the rendering performance of GT only when all the UI elements are in layers. That means you can't style your <body> and every child of your <body> must be a layer.

When using this option, there is one less texture on the GPU and also we save GPU time by not drawing this texture to the backbuffer, but drawing directly in the backbuffer. The improvement of the performance scales proportionally to the game resolution and inversely proportional to the size of the elements in the UI. For example, a 4k UI showing only a health bar will benefit more from the option than a 1080p UI with many menus.

The option doesn't work with HUD Components, but only when using a class derived from ACoherentUIGTGameHUD. Also the option isn't supported in PIE mode. The click-through feature, which allows you to determine if the mouse is on a UI Element or on the game, is also not supported when painting directly to the backbuffer.

Transition guide between GT 1.x and 2.0

  • Remove all CoherentUIGTLiveView components
  • For all <img> tags in your html that represent live views
    • In the Editor right click on the render target that the live view uses
    • Select Copy Reference
    • Replace the source of the element with the copied link

How to setup the Coherent GT license key?

There are two ways for setting it up:

  • Usually you'd want to add a LicenseGT.h file in YourEngineDir/Engine/UE4/Engine/Source/ThirdParty/CoherentUIGT/include/Coherent/UIGT which contains a static variable for the license key, i.e.:
    static const char* COHERENT_UI_GT_LICENSE = "YourLicenseKey";
    
  • Via the ICoherentUIGTPlugin::OnLicenseKey delegate. It is a single cast delegate and the function to be bound to the delegate is with the following signature: FString Function(). A convenient place, where you can bind the desired function which returns your license key is the StartupModule method of your GameModule class. Here is a pseudocode implementation:
    virtual void StartupModule() override
    {
        ICoherentUIGTPlugin::Get().OnLicenseKey.BindLambda([]()
        {
            // Get your license key...
            return FString("YourLicenseKey");
        });
    }
    
Note
If ICoherentUIGTPlugin::OnLicenseKey has no bound function, then the license key from LicenseGT.h file will be used.
Warning
Even if you choose the second option you still have to provide a LicenseGT.h file containing a COHERENT_UI_GT_LICENSE variable, e.g. static const char* COHERENT_UI_GT_LICENSE = "";

Coherent GT 2.8.2+ transition guide

Plugin structure

Starting from Coherent GT 2.8.2 the rendering part of our UE4 integration is now separated in its own plugin - CoherentRenderingPlugin. This means that CoherentUIGTPlugin has a dependency on the new rendering plugin (specified in CoherentUIGTPlugin.uplugin). That resulted in the following structural changes:

  • The FCohRenoirBackend rendering backend is now moved from CoherentUIGTPlugin to CoherentRenderingPlugin, along with all relevant source files (with a Coh prefix).
  • The FCoherentUIGTFileManipulator is now FRenderingFileManipulator and is also moved from CoherentUIGTPlugin to CoherentRenderingPlugin.
  • The Renoir public headers in RenoirBackend, RenoirBackends and RenoirCore are moved from the CoherentUIGT module (Engine/Source/ThirdParty/CoherentUIGT/include) to the new Renoir module (Engine/Source/ThirdParty/Renoir/include).
  • The Renoir import library is now packaged in the Renoir module (Engine/Source/ThirdParty/Renoir/lib) so that the module can load the Renoir dynamic library.
  • The Renoir binaries are moved from the CoherentUIGT module (Engine/Binaries/ThirdParty/CoherentUIGT) to the new Renoir module (Engine/Binaries/ThirdParty/Renoir).

This is what the new structure looks like:

|-Engine
  |-Binaries
    |-ThirdParty
      |-CoherentUIGT // No Renoir binaries and symbols in this folder anymore
      |-Renoir
        |-Win32
          |-RenoirCore.WindowsDesktop.dll
          |-RenoirCore.WindowsDesktop.pdb
        |-Win64
          |-RenoirCore.WindowsDesktop.dll
          |-RenoirCore.WindowsDesktop.pdb
        |-...
  |-Plugins
    |-Runtime
      |-Coherent
        |-CoherentRenderingPlugin
        |-CoherentUIGTPlugin
  |-Source
    |-ThirdParty
      |-CoherentUIGT
        |-include
          |-Coherent
            |-UIGT
        |-lib
      |-Renoir
        |-include
          |-RenoirBackend
          |-RenoirBackends
          |-RenoirCore
        |-lib
          |-Win32
            |-RenoirCore.WindowsDesktop.lib
          |-Win64
            |-RenoirCore.WindowsDesktop.lib
          |-...

Migration steps

Depending on whether you use our installer or an archive, there are some steps required to transition to Coherent GT 2.8.2+:

Using installer

Make sure you check the Clean install option during installation. If you don't, this will lead to compiler errors due to redefinition of Renoir-related code caused by source file duplication in both CoherentUIGTPlugin and CoherentRenderingPlugin.

Using archive & game-only plugin

If you're using Coherent GT as a game-only plugin, you will have to delete the <YourGameRoot>/Plugins/Runtime/Coherent/CoherentUIGTPlugin folder before running GamePlugin.bat. This is required to avoid that same issue mentioned in the Using installer section above.

Using versions of UE4 prior to 4.17

If you are using a version of Unreal Engine up to 4.16 (inclusive), you will have to:

  1. Manually enable the CoherentRenderingPlugin. To do that, from the main menu click Edit -> Plugins, then navigate to the User Interface section, find the Coherent Rendering plugin and click the checkbox Enabled. You'll also have to restart the editor. From UE 4.17 and onwards, the engine itself takes care of enabling dependent plugins and you don't need to do anything.
  2. Manually copy all files located inside CoherentRenderingPlugin\Shaders\Private to the Engine\Shaders folder. From UE 4.17 and onwards, the engine supports keeping shaders inside the plugin's directory so you don't have to do anything, but before that, the shader files must reside inside the Engine.