UE4 is embedded in the Web and UE4 to Web communication. I use ue4.22.3, and take UE4 embedded in ECharts and communicating with ECharts as an example.
Uwebbrowser is a plug-in class for browsing the Web provided by UE4. In order to communicate with the Web later, we need to customize a uwebbrowser class here.
1. Create a custom WebBrowser class
Right click in C++ Classes to create a C + + class of your own that inherits from the widget class - MyWebBrowser.
2. Write a custom WebBrowser
Then search WebBrowser.cpp and WebBrowser.h in VS. these are the WebBrowser classes provided by UE4. Although we write a custom WebBrowser, our custom WebBrowser is basically the same in function as the one provided by UE4, so we only need to copy the code in the WebBrowser provided by UE4 to our own MyWebBrowser for a little modification.
Of course, the copy is not a full copy, just copy the dotted part of the following WebBrowser.h to our MyWebBrowser.h. Sometimes there may be errors reported by FOnUrlChanged and FOnBeforePopup. Wait for VS to react. Sometimes it can be compiled directly, and the red report can also be compiled.
/*WebBrowser.h*/ #pragma once #include "Components/Widget.h" #include "WebBrowser.generated.h" UCLASS() class WEBBROWSERWIDGET_API UWebBrowser : 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); };
WebBrowser.cpp is copied to MyWebBrowser.cpp completely, and then all uwebbrowsers are modified to UMyWebBrowser, and "include" WebBrowser. H "is changed to our own" include "MyWebBrowser.h".
It should be noted that sometimes the "include" SWebBrowser.h "header file cannot be opened due to different engine locations. At this time, we need to give a path to SWebBrowser.h, for example:" include "Runtime/WebBrowser/Public/SWebBrowser.h".
Then the Experimental code in the following code can be modified or not. This code mainly controls the column position of our customized MyWebBrowser displayed in the Palette of UI. Here I change it to My.
#if WITH_EDITOR const FText UWebBrowser::GetPaletteCategory() { return LOCTEXT("Experimental", "Experimental"); } #endif
Then you can compile.
3. Complete code
The complete code is posted here for reference.
/*MyWebBrowser.h*/ // Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "Components/Widget.h" #include "MyWebBrowser.generated.h" UCLASS() class WEBTEST_API UMyWebBrowser : 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); };
/*MyWebBrowser.cpp*/ // Fill out your copyright notice in the Description page of Project Settings. #include "MyWebBrowser.h" #include "Runtime/WebBrowser/Public/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" ///////////////////////////////////////////////////// // UWebBrowser UMyWebBrowser::UMyWebBrowser(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { bIsVariable = true; } void UMyWebBrowser::LoadURL(FString NewURL) { if (WebBrowserWidget.IsValid()) { return WebBrowserWidget->LoadURL(NewURL); } } void UMyWebBrowser::LoadString(FString Contents, FString DummyURL) { if (WebBrowserWidget.IsValid()) { return WebBrowserWidget->LoadString(Contents, DummyURL); } } void UMyWebBrowser::ExecuteJavascript(const FString& ScriptText) { if (WebBrowserWidget.IsValid()) { return WebBrowserWidget->ExecuteJavascript(ScriptText); } } FText UMyWebBrowser::GetTitleText() const { if (WebBrowserWidget.IsValid()) { return WebBrowserWidget->GetTitleText(); } return FText::GetEmpty(); } FString UMyWebBrowser::GetUrl() const { if (WebBrowserWidget.IsValid()) { return WebBrowserWidget->GetUrl(); } return FString(); } void UMyWebBrowser::ReleaseSlateResources(bool bReleaseChildren) { Super::ReleaseSlateResources(bReleaseChildren); WebBrowserWidget.Reset(); } TSharedRef<SWidget> UMyWebBrowser::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) .OnUrlChanged(BIND_UOBJECT_DELEGATE(FOnTextChanged, HandleOnUrlChanged)) .OnBeforePopup(BIND_UOBJECT_DELEGATE(FOnBeforePopupDelegate, HandleOnBeforePopup)); return WebBrowserWidget.ToSharedRef(); } } void UMyWebBrowser::SynchronizeProperties() { Super::SynchronizeProperties(); if (WebBrowserWidget.IsValid()) { } } void UMyWebBrowser::HandleOnUrlChanged(const FText& InText) { OnUrlChanged.Broadcast(InText); } bool UMyWebBrowser::HandleOnBeforePopup(FString URL, FString Frame) { if (OnBeforePopup.IsBound()) { if (IsInGameThread()) { OnBeforePopup.Broadcast(URL, Frame); } else { // Retry on the GameThread. TWeakObjectPtr<UMyWebBrowser> 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 UMyWebBrowser::GetPaletteCategory() { return LOCTEXT("My", "My"); } #endif ///////////////////////////////////////////////////// #undef LOCTEXT_NAMESPACE2, Embed Web page
The MyWebBrowser we created inherits from Widget and belongs to UI category, so Web display operation belongs to UI operation.
1. Create UI for Web embedding
Right click / User Interface/Widget Buleprint in the Content Browser to create a UI blueprint. Here I name it WebBrowser.
Open the WebBrowser. If the above code has been compiled, there should be a My column in the Palette of the UI, and there should be a My Web Browser control in the column. This is the custom WebBrowser we created.
Drag My Web Browser into Canvas Panel in Hierachy and resize it.
2. display UI
Open the stage blueprint and write the following blueprint script:
Note that Class is filled with the UI blueprint webBrowser we just created.
3. embedding Web
Write the following blueprint script in the Graph of the UI blueprint webBrowser, and enter www.baidu.com in the New URL for testing.
Operation test
The test passed.
3, UE4 to Web communicationUE4 to Web communication. Here, take UE4 to ECharts communication as an example. First, download a chart source code you like to local to ECharts official website.
Echartsjs official website: https://www.echartsjs.com/zh/index.html
Let me take the line chart as an example
ECharts is relatively simple to start with. The official 5-minute quick start tutorial has a detailed API explanation, which is not too cumbersome here.
Here, use UE4 to set the maximum and minimum values of the Y-axis of the line graph.
1. Preparation before communication
The communication from UE4 to the Web needs to bind a communication object through a function of the SWebBrowser class, and then carry out data communication through this object.
First we need to define a function
UFUNCTION(BlueprintCallable, Category = "Web Browser") void UMyWebBrowser::BindUObject(const FString & Name, UObject * Object, bool bIsPermanent);
The function calls void SWebBrowser:: binduobject (const fstring & name, uobject * object, bool bispermanent) in the SWebBrowser class to create a communication intermediary.
Note that the BindUObject function needs to be exposed to blueprint calls.
Function realization
void UMyWebBrowser::BindUObject(const FString & Name, UObject * Object, bool bIsPermanent) { if (WebBrowserWidget.IsValid()) { WebBrowserWidget->BindUObject(Name, Object, bIsPermanent); } }
2. Create communication objects and data transfer methods
Then add the call of BindUObject to the blueprint script of the Graph in the WebBrowser to create the communication mediation object.
Among them, Name is the name of the communication intermediary object. The name can be customized. The name of the name used in the Web is called in the Web, and the intermediary object is Self, that is, the current Widget object.
The communication from UE4 to Web is that the Web actively calls the method of UE4, and the communication data is the return value of this method. The Web can obtain this return value, and the purpose of data communication can be achieved through the return value of this method in this object.
Add two methods for data transfer, GetMin and GetMax, to My Blueprint/Functions in WebBrowser.
Note here that the name of the return value of the method used for data transfer must be ReturnValue or the data cannot be transferred.
After that, you can operate in the Web to obtain Min and Max variables in UE4 through obj.
Here is the Web source code:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <!-- Introduce echarts.js --> <script src="C:/Users/Administrator/Desktop/ECharts/echarts.min.js"></script> <script src="C:/Users/Administrator/Desktop/ECharts/jquery.min.js"></script> </head> <body style = "background-color:#d8d8d8"> <!-- by ECharts Prepare a Dom --> <div id="main" style="width: 1000px;height:450px;position:1px; top:1px;">CHART</div> <script type="text/javascript"> var myChart = echarts.init(document.getElementById("main")); var x = [1,2,3,4,5,6,7,8,9,10,12,13,14,15,16,17,18,19,20,20,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40]; var y = []; var y_min = 0; var y_max = 1; function Set(){ option = { tooltip : { trigger : 'axis', //Cross anchor axisPointer: { type: 'cross', animation: false, label: {backgroundColor: '#505765'}, lineStyle : {type : 'dashed'} } }, xAxis: {data: x}, yAxis: { splitLine: {show: false }, min : y_min, max : y_max }, dataZoom: [ {startValue: '2014-06-01'}, {type: 'inside'} ], series: { type: 'line', data: y } } } function SetYMinAndMax(){ ue.obj.getmin().then(function(ReturnValue){ y_min = ReturnValue; }); ue.obj.getmax().then(function(ReturnValue){ y_max = ReturnValue; }); } function AddData(){ y.push(Math.random()); } SetYMinAndMax(); setInterval(function(){ AddData(); Set(); myChart.setOption(option); },1000); </script> </body> </html>
The SetYMinAndMax function is the data communication between UE4 and Web.
function SetYMinAndMax(){ ue.obj.getmin().then(function(ReturnValue){ y_min = ReturnValue; }); ue.obj.getmax().then(function(ReturnValue){ y_max = ReturnValue; }); }
Note also that ue.obj.getmin() and ue.obj.getmax() must be in lowercase, otherwise they cannot communicate. Secondly, the parameter name of anonymous function(ReturnValue) must also be ReturnValue, which cannot be changed, otherwise the data still cannot be transferred.
Then test whether the data transfer is correct.
[external link image transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-Cq2rABFw-1579251543050)([UE4] UE4 embeds and communicates with the Web / snipaste_-01-16_-22-57. PNG))
[the external link image transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-kniqdys-1579251543051) ([UE4] UE4 embeds and communicates with the Web / snipaste_-01-16_-23-16. PNG))
You can see that the maximum value of the Y-axis is changed from 1 to the value of the Max variable, 2. Data transfer succeeded.
To run the above Web program, you need two files, echarts.min.js and jquery.min.js. The files are:
//The SetYMinAndMax function is the data communication between UE4 and Web. ```javascript function SetYMinAndMax(){ ue.obj.getmin().then(function(ReturnValue){ y_min = ReturnValue; }); ue.obj.getmax().then(function(ReturnValue){ y_max = ReturnValue; }); }
Note also that ue.obj.getmin() and ue.obj.getmax() must be in lowercase, otherwise they cannot communicate. Secondly, the parameter name of anonymous function(ReturnValue) must also be ReturnValue, which cannot be changed, otherwise the data still cannot be transferred.
Then test whether the data transfer is correct.
You can see that the maximum value of the Y-axis is changed from 1 to the value of the Max variable, 2. Data passed successfully.
To run the above Web program, you need two files, echarts.min.js and jquery.min.js. The files are:
This is the video tutorial on site B: https://www.bilibilili.com/video/av47212309
Goulandis 25 original articles published, 20 praised, 936 visited Private letter follow