Proper use of Coherent UI in a non-basic way

So, I’m evaluating Coherent and trying to slave it to my will. I’ve read the wrapper source code, the PDF documentation and implemented it into a test application and the UE4 integration is pretty basic. Here’s what you can do:

  1. You can put a Coherent UI onto a texture in a material, as long as one of the actors using that material has a CoherentUIComponent so that it can find the texture and get the reference. Great.
  2. You can also create your own HUD and use their CoherentUIHud component to render a Coherent surface to your hud. Also great.

Here’s what you can’t easily do, as far as I can tell so far:

  1. Change the URL that the Coherent UI is rendering on your HUD. To do that, you have to change your HUD to a new one (a new CoherentUIHud component, actually). I have issues with this, see below.
  2. Change the URL that the Coherent UI is rendering on your surface. To do that you need to do as above, get another CoherentUIComponent.

These two deficiencies make some large problems. First, spinning up a Coherent UI is async, which is bad for a UI. So to alleviate this issue, I want to init some or all of the complex UIs in the background and have them sitting there ready to go. Unfortunately because of the structure of the system, this is difficult. The “friendly” nature of the two components causes them to register themselves for things like input updates on creation. The only way to unregister them from the internal updates is to unregister the component. There doesn’t seem to be a notion of a dormant UI. There’s also the issue that I don’t know what’s happening on the other side - is Coherent rendering all active views every frame?

The solution seems to be to write my own version of some of the UE4 classes for Coherent. This seems crazy.

There’s also some UE4 issues as well. What if I want to layer my UI? I want a HUD, with an inventory pop out window and optionally a yes/no dialog. The top most dialog is the active one (the Y/N dialog), but the other two are still rendered. As far as I can tell using the “HUD” system, the only way that works is if all of that stuff is one giant Coherent UI.

So, some questions

I haven’t figured it out yet, and it looks ugly, but how do I orthographically project multiple Canvas objects in a layered way on top of the players camera? The code right now appears to be creating one every time it renders. There doesn’t appear to be a hookable path to this.

Has anyone used Coherent in UE4 in a non-basic way and worked around the issues I’ve brought up? Are there some obvious fixes I am overlooking?

Hi there,

UCoherentBaseComponent, which is the parent of both surface/HUD Coherent UI components, provides various methods and notifications for manipulating the View. Unless I’m missing something in your use case, you can just call the Load(const FString& Path) method to change the URL, there’s no need to create another component.

The surface/HUD components actually register themselves only for drawing callbacks. Each view is drawn only if there’s a change in the frame - if it’s static, then Coherent UI doesn’t render new frames. You can check this in the FCoherentUIViewListener::OnDraw callback, which is executed on each new frame. If you have a complex page that loads slowly, you can add a handler for the FinishLoad event like so:

CoherentHUD->FinishLoad.AddDynamic(this, &ASomeActor::OnFinishLoad);

and draw the view only after you received the notification so the user doesn’t see the layout process.

Input is handled through our input widget and it does indeed not take into account if the view is visible or not. We’ll be extending the system so this case is supported, and in the meantime a quick solution would be to add a new property in UCoherentBaseComponent which tells if the component should receive input and test for this property in the various SCoherentInputForward methods.

Multiple HUD components are supported as well - you can easily add more than one in your HUD actor and draw them in the DrawHUD method as you wish - e.g. don’t draw the HUD when the inventory is shown and vice versa. There is of course the option of one big page that hosts all HUD elements. There are various frameworks for writing modular HTML (i.e. combining multiple HTML files into one page at runtime) that can be used; you can also employ some basic JavaScript to show/hide elements on the fly.

– Nick

Thanks for the useful answer Nick, I have been digging in and am working on a solution that meets my requirements. It looks like it should be fairly easy to get Coherent to work how I want it to in my project. I’ll put up a wiki article showing what I’ve come up with when I get something working.

Thanks for the great support.

Just curious @backov did you ever have time to create an article for the wiki in relation to how you accomplished the tasks you were after using Coherent UI? If so, a link would be great! Thanks.

Sorry man, I switched to Radiant which is OSS and fine for my indie needs.