源码分析
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);
};
														
				
												
近期评论