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:
#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;
};
#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.