FAQ

I see Cohtml used in some places in code / docs. What’s that?

Cohtml is the C++ library that powers Prysm. It does most of the work on your UI. Appropriately, the Unreal Engine plugin is technically named CohtmlPlugin and all of its classes start with Cohtml. When working in the Unreal Editor, however, we believe it’s easier for users to instead see the name of the product as it is and that’s why you’ll see Prysm. Consider Cohtml and Prysm to be mostly interchangeable.

Can I load files over HTTP(S)?

Absolutely! The plugin uses Unreal’s HTTP module to download files whenever Prysm detects file requests over HTTP(S). You can download everything from the web (e.g. by setting the root URL of the page to use HTTP) or you can download just some files like images or data (e.g. via AJAX).

Check the example level /Maps/HTTPMap in the CoherentSample game that comes with the plugin for a demo.

Can I use a gamepad to control my UI?

Certainly! Prysm uses Unreal’s gamepad data to expose the HTML5 Gamepad API. You don’t have to do anything on the game’s side to enable the gamepad input, simply connect your controller, focus the UI and you’re good to go. See the ExampleMap for a sample that utilizes this functionality.

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

How to seamlessly travel between levels with Prysm enabled?

You need to make a few changes to your code to use seamless traveling with Prysm.

  1. All the Prysm Components that you’d like to preserve to the next level must have their parent actors added to the list of traveling Actors.
  2. The unique instance of Prysm’s ACohtmlSystem 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 Prysm components are tagged with “PreservePrysm”):

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

Finally, make sure that no ACohtmlSystem 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 behavior (such as time passing by faster than it should).

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

The System will set all buttons and axes to zero 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 behavior by calling ACohtmlInputActor::GetGamepadBehaviourDelegate() which will return a delegate you can bind your callback to. For example

auto MyFunc = [](uint32 UserId) -> ECohtmlGamepadBehaviourOnFocusLost
{
    return ECohtmlGamepadBehaviourOnFocusLost::CohtmlResetState;
}
InputActor->ACohtmlInputActor::GetGamepadBehaviourDelegate().BindLambda(MyFunc);

Your function has to return one of these values:

  • ECohtmlGamepadBehaviourOnFocusLost::CohtmlResetState - Set the current state to zero. This is default behavior.
  • ECohtmlGamepadBehaviourOnFocusLost::CohtmlUseCurrentState - Will keep the last known state. Note that this will trigger the behavior mentioned above.
  • ECohtmlGamepadBehaviourOnFocusLost::CohtmlUseStateBeforeReset - 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

How do I localize my game?

  1. Follow UE’s localization tutorial to setup the required translations.

  2. Inside the Unreal Editor, go to Prysm -> 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 to enable line-wrap for Asian texts

There is an option to enable the internationalization Break Iterator which will enable line-wrap for Asian texts. See the Break Iterator option for more details.

Building a UE dedicated server

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

You can check the whole procedure of cooking the data for your server and building it in the Unreal Community Wiki.

Our UI uses a lot of fonts, can I tell Prysm to load them all?

Yes, any font placed in /Game/Content/Fonts will be automatically loaded when the game starts. Please note that Prysm requires the raw .ttf and .otf files (not the .uasset files that Unreal 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.

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

Simply go to Prysm -> 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 Prysm component and tick Delayed Update), or enable it using SetupView (the bDelayedUpdate argument - false by default). Alternatively, you can use EnableDelayedUpdate(true) on the Component - available in both Blueprints and C++.

Can I use RenderDoc/PIX with Prysm?

Yes - both are supported, as long as you follow the steps below:

  • Make sure that you set EmitRenderingMetadata in the CohtmlViewSettings to true when creating your View. This incurs a significant performance overhead, so use it only for debugging.
  • (Optional) It is highly recommended you also set ContinuousRepaint to true for the View you are debugging. This will force every View frame to be redrawn from scratch, so that that all graphic backend commands are present in your capture. Note that ContinuousRepaint is automatically set to false inside FCohtmlViewWrapper::Tick(), so you would need to modify it first.
  • Make sure that UE’s RHI_COMMAND_LIST_DEBUG_TRACES macro is set to 1. You can do this directly inside Engine\Source\Runtime\RHI.h or through your game configuration.
  • If you are using PIX, you are required to use a DirectX 12 graphics backend, so make sure that you are passing the -dx12 command line flag to your game.

Saving Debug Render Frames

You can use DebugSaveNextFrame and BeginDebugFrameSave methods on Prysm Components/UMG Widget, which will capture rendering frames and save them to files in GameDir/Saved/Prysm/ 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 artifact, you can send them to our support team for investigation.

Part of my UI seems blurry when moving. What’s causing this?

This is caused by the anti-aliasing algorithm used by Unreal Engine. When Temporal AA is used (Unreal’s default choice), the in-game UI will be blurry.

How to fix it: Change the anti-aliasing algorithm to FXAA, or disable AA.

If Temporal AA is needed:

  1. Open the default rendering Material from the Contents directory of the plugin.
  2. Check Responsive AA property in Translucency tab in the Details of the material.