源码分析
Webrowser是虚幻官方的webUi插件,但插件本身默认被锁了24FPS,导致部分动画看起来很卡段不连贯
其他修改浏览器参数的需求也可参照此文章
在虚幻引擎的安装目录:\Engine\Plugins\Runtime\WebBrowserWidget\Source\WebBrowserWidget\Private下可以看到webbrowser的源码,但是下载的安装版是无法修改此源码的,即便修改也无法编译,所以如果要实现自定义的浏览器,那就有两种方法:
- 下载虚幻源码自编译
- 仿照其写一个浏览器控件并调用
显然第一点的代价很大,所以接下来采取第二个方法
通过源码可以得知,这个浏览器控件其实是对“SBrowser”的实例化,cpp文件90行左右有如下代码:
WebBrowserWidget = SNew(SWebBrowser)
.InitialURL(InitialURL)
.ShowControls(false)
.SupportsTransparency(bSupportsTransparency)
.OnUrlChanged(BIND_UOBJECT_DELEGATE(FOnTextChanged, HandleOnUrlChanged))
.OnBeforePopup(BIND_UOBJECT_DELEGATE(FOnBeforePopupDelegate, HandleOnBeforePopup));
return WebBrowserWidget.ToSharedRef();
查看SWebBrowser的实现(直接资源管理器搜索这个文件即可),可看到其有对各种参数的定义,其中就有帧率限制:
SLATE_BEGIN_ARGS(SWebBrowser)
: _InitialURL(TEXT("https://www.google.com"))
, _ShowControls(true)
, _ShowAddressBar(false)
, _ShowErrorMessage(true)
, _SupportsTransparency(false)
, _SupportsThumbMouseButtonNavigation(true)
, _ShowInitialThrobber(true)
, _BackgroundColor(255,255,255,255)
, _BrowserFrameRate(24)
, _PopupMenuMethod(TOptional<EPopupMethod>())
, _ViewportSize(FVector2D::ZeroVector)
{ }
//。。下面还有很多参数,可以自行查看
到这里思路就比较清晰了,如果使用自编译源码的话,直接把24改了就好了,但是如果不是自编译,就需要另外搞事情。
自定义浏览器widget
新建C++类,名字随意,这里以WebBrowser60为例,意为60FPS的浏览器。
CPP文件和H文件直接照搬WebBrowser,如果没有特殊需求的话。
在初始化SBrowser的位置加上一句对参数的设定就行,理论上参数是都能设置的
WebBrowserWidget = SNew(SWebBrowser)
.InitialURL(InitialURL)
.ShowControls(false)
.SupportsTransparency(bSupportsTransparency)
//重点在这里
.BrowserFrameRate(60)
//重点在这里
.OnUrlChanged(BIND_UOBJECT_DELEGATE(FOnTextChanged, HandleOnUrlChanged))
.OnBeforePopup(BIND_UOBJECT_DELEGATE(FOnBeforePopupDelegate, HandleOnBeforePopup));
下面是整个cpp和h的文件代码,可以直接copy
UWebBrowser60.cpp
// Copyright Epic Games, Inc. All Rights Reserved.
#include "WebBrowser60.h"
#include "SWebBrowser.h"
#include "Widgets/Layout/SBox.h"
#include "Widgets/Text/STextBlock.h"
#include "Async/TaskGraphInterfaces.h"
#include "UObject/ConstructorHelpers.h"
#if WITH_EDITOR
#include "Materials/MaterialInterface.h"
#include "Materials/MaterialExpressionMaterialFunctionCall.h"
#include "Materials/MaterialExpressionTextureSample.h"
#include "Materials/MaterialExpressionTextureSampleParameter2D.h"
#include "Materials/MaterialFunction.h"
#include "Factories/MaterialFactoryNew.h"
#include "AssetRegistryModule.h"
#include "PackageHelperFunctions.h"
#endif
#define LOCTEXT_NAMESPACE "WebBrowser"
/////////////////////////////////////////////////////
// UWebBrowser60
UWebBrowser60::UWebBrowser60(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
bIsVariable = true;
}
void UWebBrowser60::LoadURL(FString NewURL)
{
if (WebBrowserWidget.IsValid())
{
return WebBrowserWidget->LoadURL(NewURL);
}
}
void UWebBrowser60::LoadString(FString Contents, FString DummyURL)
{
if (WebBrowserWidget.IsValid())
{
return WebBrowserWidget->LoadString(Contents, DummyURL);
}
}
void UWebBrowser60::ExecuteJavascript(const FString& ScriptText)
{
if (WebBrowserWidget.IsValid())
{
return WebBrowserWidget->ExecuteJavascript(ScriptText);
}
}
FText UWebBrowser60::GetTitleText() const
{
if (WebBrowserWidget.IsValid())
{
return WebBrowserWidget->GetTitleText();
}
return FText::GetEmpty();
}
FString UWebBrowser60::GetUrl() const
{
if (WebBrowserWidget.IsValid())
{
return WebBrowserWidget->GetUrl();
}
return FString();
}
void UWebBrowser60::ReleaseSlateResources(bool bReleaseChildren)
{
Super::ReleaseSlateResources(bReleaseChildren);
WebBrowserWidget.Reset();
}
TSharedRef<SWidget> UWebBrowser60::RebuildWidget()
{
if (IsDesignTime())
{
return SNew(SBox)
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Text(LOCTEXT("Web Browser", "Web Browser"))
];
}
else
{
WebBrowserWidget = SNew(SWebBrowser)
.InitialURL(InitialURL)
.ShowControls(false)
.SupportsTransparency(bSupportsTransparency)
.BrowserFrameRate(60)
.OnUrlChanged(BIND_UOBJECT_DELEGATE(FOnTextChanged, HandleOnUrlChanged))
.OnBeforePopup(BIND_UOBJECT_DELEGATE(FOnBeforePopupDelegate, HandleOnBeforePopup));
return WebBrowserWidget.ToSharedRef();
}
}
void UWebBrowser60::SynchronizeProperties()
{
Super::SynchronizeProperties();
if (WebBrowserWidget.IsValid())
{
}
}
void UWebBrowser60::HandleOnUrlChanged(const FText& InText)
{
OnUrlChanged.Broadcast(InText);
}
bool UWebBrowser60::HandleOnBeforePopup(FString URL, FString Frame)
{
if (OnBeforePopup.IsBound())
{
if (IsInGameThread())
{
OnBeforePopup.Broadcast(URL, Frame);
}
else
{
// Retry on the GameThread.
TWeakObjectPtr<UWebBrowser60> WeakThis = this;
FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, URL, Frame]()
{
if (WeakThis.IsValid())
{
WeakThis->HandleOnBeforePopup(URL, Frame);
}
}, TStatId(), nullptr, ENamedThreads::GameThread);
}
return true;
}
return false;
}
#if WITH_EDITOR
const FText UWebBrowser60::GetPaletteCategory()
{
return LOCTEXT("Experimental", "Experimental");
}
#endif
/////////////////////////////////////////////////////
#undef LOCTEXT_NAMESPACE
UWebBrowser60.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
/*MyWebBrowser.h*/
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "Components/Widget.h"
#include "WebBrowser60.generated.h"
/**
*
*/
UCLASS()
class DIGITALTWINPLATFORM_API UWebBrowser60 : public UWidget
{
GENERATED_UCLASS_BODY()
public:
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnUrlChanged, const FText&, Text);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnBeforePopup, FString, URL, FString, Frame);
/**
* Load the specified URL
*
* @param NewURL New URL to load
*/
UFUNCTION(BlueprintCallable, Category = "Web Browser")
void LoadURL(FString NewURL);
/**
* Load a string as data to create a web page
*
* @param Contents String to load
* @param DummyURL Dummy URL for the page
*/
UFUNCTION(BlueprintCallable, Category="Web Browser")
void LoadString(FString Contents, FString DummyURL);
/**
* Executes a JavaScript string in the context of the web page
*
* @param ScriptText JavaScript string to execute
*/
UFUNCTION(BlueprintCallable, Category = "Web Browser")
void ExecuteJavascript(const FString& ScriptText);
/**
* Get the current title of the web page
*/
UFUNCTION(BlueprintCallable, Category="Web Browser")
FText GetTitleText() const;
/**
* Gets the currently loaded URL.
*
* @return The URL, or empty string if no document is loaded.
*/
UFUNCTION(BlueprintCallable, Category = "Web Browser")
FString GetUrl() const;
/** Called when the Url changes. */
UPROPERTY(BlueprintAssignable, Category = "Web Browser|Event")
FOnUrlChanged OnUrlChanged;
/** Called when a popup is about to spawn. */
UPROPERTY(BlueprintAssignable, Category = "Web Browser|Event")
FOnBeforePopup OnBeforePopup;
public:
//~ Begin UWidget interface
virtual void SynchronizeProperties() override;
// End UWidget interface
virtual void ReleaseSlateResources(bool bReleaseChildren) override;
#if WITH_EDITOR
virtual const FText GetPaletteCategory() override;
#endif
protected:
/** URL that the browser will initially navigate to. The URL should include the protocol, eg http:// */
UPROPERTY(EditAnywhere, Category=Appearance)
FString InitialURL;
/** Should the browser window support transparency. */
UPROPERTY(EditAnywhere, Category=Appearance)
bool bSupportsTransparency;
protected:
TSharedPtr<class SWebBrowser> WebBrowserWidget;
protected:
// UWidget interface
virtual TSharedRef<SWidget> RebuildWidget() override;
// End of UWidget interface
void HandleOnUrlChanged(const FText& Text);
bool HandleOnBeforePopup(FString URL, FString Frame);
};
近期评论