Announcement

Collapse
No announcement yet.

FREE: Web UI (HTML/CSS/JS Interface)

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    FREE: Web UI (HTML/CSS/JS Interface)


    The WebUI plugin allows developers to create rich web-based user interfaces using blueprints. It's powered by the native UnrealCEFSubProcess built into the engine and includes support for Windows, Mac, Linux, Android (4.19+) and iOS (4.21+). This plugin also includes a robust JSON library that provides integrated management of objects, arrays, and primitive data types. It comes with an example project that demonstrates a startup map with a volume slider and FPS counter. This plugin includes multiplayer support by removing the CEF in dedicated server builds without changing any blueprint classes.







    You must have a GitHub account linked to your Epic Games account! Otherwise you will receive the following 404 error if you are not signed in with a linked account.

    Setup Instructions: unrealengine.com/ue4-on-github



    Frequently Asked Questions

    Can I use this plugin for off-screen compositing?

    Yes, there's a couple options depending on what functionality you require. The internal rendering of the WebInterface widget can't be accessed in blueprints so there isn't an easy way to directly reference a texture. However you can use a URetainerBox to apply a post process material using a texture parameter or add a UWidgetComponent to your blueprint which renders the widget to a render target texture.

    Can I put the interface on 3D objects in the world?

    Yes, if you use a URetainerBox it provides a texture parameter to an effect material which you can reference at runtime using GetEffectMaterial. This dynamic material instance can be applied to a UMeshComponent using SetMaterial. Another option is to use a UWidgetComponent as a wrapper because essentially it's only purpose is to provide access to a render target texture. If the component isn't visible you can still use the GetRenderTarget function to obtain a Texture2D reference. These textures can also be applied to a UMeshComponent using CreateDynamicMaterialInstance and SetTextureParameterValue.

    What kind of performance can I expect?

    The WebInterface widget runs on the same UnrealCEFSubProcess as the WebBrowser widget. It just adds the ability to transmit JSON to the engine from JavaScript, but you can already send JavaScript to the browser from the engine. That means you can test the performance by enabling the WebBrowser plugin that comes with the engine and try experimenting with that beforehand.

    Do you have any tips to improve performance?

    Yes, but please note that the CEF can already meet the needs of most games unless the UI needs to be an integral component of the gameplay. Some performance tips for now would be to utilize a transparent background to reduce the size of paint regions. You can also disable frame buffering by unsetting USE_BUFFERED_VIDEO. Another option is to manually set the subprocess frame rate in your engine source code.

    Are there any third-party dependencies in this plugin?

    No, the Web UI plugin does not have any third-party dependencies at this time. It uses the native UnrealCEFSubProcess built into the engine which runs on the Chromium Embedded Framework. This is already included for Windows and Mac with all versions of UE4 since 4.8 and 4.15 added Linux support. While the plugin is not provided for versions below 4.16 it can still be manually compiled for lower versions of the engine. Please check our documentation PDF for instructions on how to compile this plugin for versions 4.15 and below.
    Last edited by spidershift; 04-16-2019, 12:32 AM.

    #2
    This is great, thanks for providing it.

    Comment


      #3
      Great plugin! I know Epic have a backlogged bug regarding custom cursors causing duplicate pointers when using the web browser.
      Any idea for a work around?

      Comment


        #4
        Originally posted by Jiyko View Post
        Great plugin! I know Epic have a backlogged bug regarding custom cursors causing duplicate pointers when using the web browser.
        Any idea for a work around?
        Sorry for the late reply I don't check the forums very often. I haven't tested custom cursors so I'm not aware of any cursor issues with the web browser. But I will definitely keep it in mind and let you know if I notice any problems or come across a solution.

        Comment


          #5
          Such an amazing plugin! Thanks for this!

          Is this topic an appropriate place to ask any questions related to this plugin?

          However I will ask, if you consider that it's unnapropriate please tell me, I'll remove this comment.

          So my questions are.

          I have this WebUI Set up as written down in documentation.
          Then I have 4 separate levels, and 4 different gamemodes respectively.
          The HUD set for this game modes are the WebUI Hud for each of them
          I share data between this levels using GameInstance class.

          The problem is that the UI is reloaded again each time a OpenLevel is called.

          1.) How I can make the WebUI persistent across all levels, without stream levels if possible


          2.) Is it possible to remove the loader in the beginning?

          3.) Is it possible to set game and UI input mode and the event propagation from the UI to only trigger on actual elements and not on transparent canvas.
          So when I will set some buttons on the bottom using fullscreen webui, my player controller inputs should also work
          Last edited by One.xi; 02-22-2019, 04:57 PM.

          Comment


            #6
            I don't get it, is this plugin also forgotten? Why using WEB technologies for HUD in UE4 is not an awesome idea so everyone should be hyped about?

            Comment


              #7

              Originally posted by One.xi View Post
              Such an amazing plugin! Thanks for this!

              Is this topic an appropriate place to ask any questions related to this plugin?

              However I will ask, if you consider that it's unnapropriate please tell me, I'll remove this comment.

              So my questions are.

              I have this WebUI Set up as written down in documentation.
              Then I have 4 separate levels, and 4 different gamemodes respectively.
              The HUD set for this game modes are the WebUI Hud for each of them
              I share data between this levels using GameInstance class.

              The problem is that the UI is reloaded again each time a OpenLevel is called.

              1.) How I can make the WebUI persistent across all levels, without stream levels if possible


              2.) Is it possible to remove the loader in the beginning?

              3.) Is it possible to set game and UI input mode and the event propagation from the UI to only trigger on actual elements and not on transparent canvas.
              So when I will set some buttons on the bottom using fullscreen webui, my player controller inputs should also work

              Great questions! I've actually dealt with a lot of these issues that you raised and should be able to answer most of your questions.

              For starters, to make a widget persistent between level changes requires some C++ to disable calling RemoveFromParent() before the level is unloaded:

              Code:
              #pragma once
              
              #include "CoreMinimal.h"
              #include "Blueprint/UserWidget.h"
              #include "PersistentUserWidget.generated.h"
              
              UCLASS(Abstract, EditInlineNew, BlueprintType, Blueprintable, meta=(DontUseGenericSpawnObject="True"))
              class WEBUI_API UPersistentUserWidget : public UUserWidget
              {
                  GENERATED_UCLASS_BODY()
              
              public:
              
                  virtual void OnLevelRemovedFromWorld( ULevel* InLevel, UWorld* InWorld ) override;
              };
              Code:
              #include "PersistentUserWidget.h"
              
              UPersistentUserWidget::UPersistentUserWidget( const FObjectInitializer& ObjectInitializer )
                  : Super( ObjectInitializer )
              {
                  //
              }
              
              void UPersistentUserWidget::OnLevelRemovedFromWorld( ULevel* InLevel, UWorld* InWorld )
              {
                  // If the InLevel is null, it's a signal that the entire world is about to disappear, so
                  // go ahead and remove this widget from the viewport, it could be holding onto too many
                  // dangerous actor references that won't carry over into the next world.
                  if ( InLevel == nullptr && InWorld == GetWorld() )
                  {
                      //RemoveFromParent();
                  }
              }
              I'll make a note to add this PersistentUserWidget to the 4.22 version of the plugin for blueprint-only projects. If you check out the comments in the code, be sure not to reference anything other than WebUI widgets in this blueprint or your game could crash.

              Yes you can hide the loader, but it is unfortunately built-in to the engine code. However the example project already demonstrates how to solve this problem. When adding your widget to the viewport, set its initial visibility to hidden. Then setup a JavaScript ready event handler which notifies your blueprint that the page has fully loaded the DOM. This "ready" event can subsequently change the visibility of your widget, and you will not see the loader.

              There is no way to redirect click events through the transparent part of the canvas directly in the engine. That requires JavaScript to do the DOM element detection and relay back to blueprints to generate a click event underneath the widget if the event bubbled up to document.click() or $('body').click() as well. But that would most likely create a laggy experience for anything gameplay related.

              However one way to work around this is to use multiple WebUI widgets that are docked to the sides of the screen or wherever you'd like. Then players can still click around these widgets since the transparent areas are now actually transparent in the viewport. So while a single fullscreen widget is best for most scenarios, sometimes breaking your interface up into smaller widgets can at least give you some access to things underneath the interface.

              Comment


                #8
                Wow, thank you SO MUCH for the answer.

                1. For the persistent UI that is a great find, million thanks. I will try this right now.

                2. Thanks for the idea! But I recently found a simpler method just need to use ShowInitialThrobber(false) in the inputs of the widget.

                3. It's a pitty that there isn't any build in solution for that, as I said above I also didn't see any other solution then passing in and out the dom element detection, and then setting the visibility of the widget. I will investigate this further, as I don't like the solution to split the ui elements to different widgets. I want an integral solution for this.

                Thanks you so much!
                Last edited by One.xi; 03-01-2019, 01:24 AM.

                Comment


                  #9
                  No problem, happy to help!

                  Yes that is a good point about the ShowInitialThrobber(false) but I believe the thinking behind leaving it enabled was that some developers might still want the simple loader to represent the interface is loading or perhaps didn't want them to think nothing was happening at all in case they ran into a loading issue.

                  However if you're looking to hide the loader and create a more seamless experience I would highly recommend considering a handshake system. What I mean is you have the WebUI widget initially hidden and your HTML/CSS/JS to have everything in the DOM also hidden on load. Then as previously mentioned the interface can notify the engine in blueprints that the DOM is ready but now all the HTML/CSS is hidden, so when the engine makes the widget visible the first render frame is guaranteed to be transparent and there's no opportunity for any weird glitches we've noticed during debugging with many of our testers over the years (such as occasional white flickers or weird renders prior to page load).

                  Now you can have the engine relay back to the browser that the widget is visible and JS can trigger any of your initial fades or animations to present your interface. This provides a seamless load and some peace of mind that the engine isn't going to do anything weird, but it is just my recommendation and you should of course do whatever works best for you.

                  Also keep in mind, while it is not ideal, you could use a combination of the methods I previously laid out for clicking underneath the interface. So for instance, if you don't want to sacrifice fullscreen animations and whatnot, then don't, just use a "hit test invisible" fullscreen WebUI widget behind a few smaller "visible" WebUI widgets that are actually clickable/focusable. Now you can have fullscreen anything but still isolate clickable areas to what form elements you overlay on top.

                  Again while this not ideal because you're basically keeping a non-clickable fullscreen widget in-sync with a bunch of small clickable ones, it's about the best I can come up with at this point until an in-process web interface is available such as WebKit that can execute JS events in engine ticks.

                  Comment


                    #10
                    Originally posted by Jiyko View Post
                    Great plugin! I know Epic have a backlogged bug regarding custom cursors causing duplicate pointers when using the web browser.
                    Any idea for a work around?
                    Have you found any solution to this?
                    I can confirm I have the same problem

                    Comment


                      #11
                      Spidershift hello again, sorry for bothering you, I thought of an idea of getiting current texture referenced in webui material and use it's pixel data to verify which pixel is completly transparent and if it is it will set the widget visibility to hit test invisible, and if the pixel from the x, y of the mouse current position will not be transparent then set the widget visibility to visible. It will run this check on every tick. What do you think of this solution to handle the "click through" transparent zones of the web ui layer? Is it viable?

                      Comment


                        #12
                        what happen? I can't find webui plugin in ue4 market or github, where and how can i get it ?

                        Comment


                          #13
                          Originally posted by ue4wing View Post
                          what happen? I can't find webui plugin in ue4 market or github, where and how can i get it ?

                          It is here, for free

                          https://github.com/tracerinteractive...ngine/releases

                          And it is an amazing plugin!

                          Comment


                            #14
                            Originally posted by gon. View Post
                            Have you found any solution to this?
                            I can confirm I have the same problem
                            I unfortunately have not looked into this problem just yet. I understand custom cursors are common in certain games but it's not a high priority at this time since you can just not use custom cursors (or for the time being hide the engine cursor and render your own widget/brush at the cursor location). I will definitely look into this issue whenever I get a chance to experiment with custom cursors, I just haven't done so for any game at this point.


                            Originally posted by One.xi View Post
                            Spidershift hello again, sorry for bothering you, I thought of an idea of getiting current texture referenced in webui material and use it's pixel data to verify which pixel is completly transparent and if it is it will set the widget visibility to hit test invisible, and if the pixel from the x, y of the mouse current position will not be transparent then set the widget visibility to visible. It will run this check on every tick. What do you think of this solution to handle the "click through" transparent zones of the web ui layer? Is it viable?
                            That is a really great idea! I was hyper-focused on JavaScript and whether DOM elements were actually clickable or not. But that would be an awesome way to approximate the interface using some kind of opacity threshold similar to how materials have 0.333 for opacity masks. As I noted in the FAQ you can use a URetainerBox to render a widget directly to a UTextureRenderTarget2D which can be used with the ReadRenderTargetPixel() function. Once we have that pixel data we can reroute the click events based on the opacity threshold or perhaps just toggle hit test visibility as you mentioned.

                            I will look more into this and see if I can develop some kind of viable solution. Thanks for the suggestion!
                            Last edited by spidershift; 04-13-2019, 10:04 AM.

                            Comment


                              #15
                              Originally posted by ue4wing View Post
                              what happen? I can't find webui plugin in ue4 market or github, where and how can i get it ?
                              You can still find the plugin (for versions 4.16-4.20) on the marketplace via your library tab in the Epic Games Launcher. However it has been deactivated so it doesn't show up in a search anymore and you cannot add it to your library if you hadn't already.

                              As mentioned the plugin is free and on GitHub, but you will need to link your Epic Games account to your GitHub account using the instructions at unrealengine.com/ue4-on-github since the repository is private. Otherwise you will see the following 404 error page:



                              This is due to the terms and conditions of the Unreal Engine EULA: "Any public Distribution (i.e., intended for Engine Licensees generally) which includes Engine Tools (including as modified by you under the License) must take place either through the Marketplace (e.g., for distributing a Product’s modding tool or editor to end users) or through a fork of Epic’s GitHub UnrealEngine Network (e.g., for distributing source code)."

                              Even though this specific plugin isn't classified as "engine tools" we plan to distribute modding plugins in the future. Therefore if our plugins are no longer being distributed on the marketplace we will have the least restrictions by distributing within the private Epic Games network on GitHub.
                              Last edited by spidershift; 04-13-2019, 10:13 AM.

                              Comment

                              Working...
                              X