x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Is it possible to include HTML5 JS files from the project or plugin?

I plan on creating an HTML5 plugin that injects utility.js so that some of my HTML5 code is blueprintable. I'll provide some custorm JS and some custom Blueprint classes. The BP implementation will call the HTML5 code with callbacks that will invoke BP delegates.

The current HTML5 JS build process combines JS templates in the build process using only the JS templates from the editor installation folder.

https://github.com/EpicGames/UnrealEngine/blob/master/Engine/Source/Programs/AutomationTool/HTML5/HTML5Platform.Automation.cs#L146

     // Gather utlity .js files and combine into one file
     string[] UtilityJavaScriptFiles = Directory.GetFiles(JSDir, "*.js");

     string DestinationFile = OutDir + "/Utility.js";
     File.Delete(DestinationFile);
     foreach( var UtilityFile in UtilityJavaScriptFiles)
     {
         string Data = File.ReadAllText(UtilityFile);
         File.AppendAllText(DestinationFile, Data);
     }

This process should be changed to also pick up any JS files from the project and from the plugins.

Any JS files that are found in ProjectName\Build\HTML5 should be picked up.

Also any JS files that are found in ProjectName\Plugins\PluginName\Build\HTML5 should be picked up.

That will allow projects and plugins to provide JS to be included in the build.

In the meantime, projects and plugins have to manually copy custom JS here:

C:\Program Files (x86)\Epic Games\4.14\Engine\Build\HTML5

This should make including JS script easier than copying custom scripts to the program files.

Product Version: UE 4.14
Tags:
more ▼

asked Feb 13 '17 at 06:45 PM in Packaging & Deployment

avatar image

tgraupmann
112 16 23 81

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

4 answers: sort voted first

Both versions work in these sample projects.

HTML5 can be included from game source. https://github.com/tgraupmann/UE4HTML5SampleSource

HTML5 can be included from a plugin. https://github.com/tgraupmann/UE4HTML5SamplePlugin

Communication works both ways.

C++ can invoke JS functions.

C++ can invoke JS to set a callback.

JS can use the callback to invoke C++ code.

alt text

more ▼

answered Aug 01 '19 at 02:42 AM

avatar image

timg_razer
21 2 2

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

I created a Pull Request to add this feature.

Add support for including project and plugin JS

https://github.com/EpicGames/UnrealEngine/pull/3251

https://github.com/EpicGames/UnrealEngine/blob/master/Engine/Source/Programs/AutomationTool/HTML5/HTML5Platform.Automation.cs#L146

Added code:

         // Gather utlity .js files and combine into one file
         string[] UtilityJavaScriptFiles = Directory.GetFiles(JSDir, "*.js");
 
         string DestinationFile = OutDir + "/Utility.js";
         File.Delete(DestinationFile);
         foreach( var UtilityFile in UtilityJavaScriptFiles)
         {
             string Data = File.ReadAllText(UtilityFile);
             File.AppendAllText(DestinationFile, Data);
         }
 
         // Gather utlity .js files from project and combine into one file
         string ProjectJSDir = Path.Combine(Path.GetDirectoryName(Params.RawProjectPath.FullName), "Build", "HTML5");
         if (Directory.Exists(ProjectJSDir))
         {
             UtilityJavaScriptFiles = Directory.GetFiles(ProjectJSDir, "*.js");
             foreach (var UtilityFile in UtilityJavaScriptFiles)
             {
                 string Data = File.ReadAllText(UtilityFile);
                 File.AppendAllText(DestinationFile, Data);
             }
         }
 
         // Gather utlity .js files from plugins and combine into one file
         string ProjectPluginsDir = Path.Combine(Path.GetDirectoryName(Params.RawProjectPath.FullName), "Plugins");
         if (Directory.Exists(ProjectPluginsDir))
         {
             foreach (var PluginName in Directory.GetDirectories(ProjectPluginsDir))
             {
                 string PluginJSDir = Path.Combine(PluginName, "Build", "HTML5");
                 if (!Directory.Exists(PluginJSDir))
                 {
                     continue;
                 }
                 UtilityJavaScriptFiles = Directory.GetFiles(PluginJSDir, "*.js");
                 foreach (var UtilityFile in UtilityJavaScriptFiles)
                 {
                     string Data = File.ReadAllText(UtilityFile);
                     File.AppendAllText(DestinationFile, Data);
                 }
             }
         }
more ▼

answered Feb 14 '17 at 06:32 PM

avatar image

tgraupmann
112 16 23 81

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

replied at: https://github.com/EpicGames/UnrealEngine/pull/3251#issuecomment-280066700

to close this thread: what you're looking for already exists within the Engine architecture. please take a look at:

you can use that as starting basis for your plugin.

more ▼

answered Feb 15 '17 at 04:50 PM

avatar image

nick.shin STAFF
481 5 4 10

avatar image Nybörjaren123 Jul 15 '19 at 11:03 AM

Does this mean you should not use emscripten but instead JS directly to setup communication between HTML and UE4?. Can you explain more as i don't really understand this. What i'm looking for is ways to communicate with blueprints i create in UE4 and then package to HTML5 and then call with html/js/react in the browser. I've used VaRest to communicate between bp and html ,but when packaging UE4 to HTML5 i get an error in the browser when loading webgl, which i guess is because of the plugin VaRest. So i'm now trying to find a more stable way to setup communcation in the browser.

avatar image nick.shin STAFF Jul 29 '19 at 06:07 PM

think of emscripten is a "compiler" -- this translates the C++ code to (what we now use) WebAssembly (think of this as binary efficient javascript for the web browser).

that said, let's try a demo. to use the files in the attached zip:

  • create a C++ First Person template, and NAME it: CPP_FP

  • unzip the attached zipfile and drop it in Source/.

  • package for HTML5

  • open a command prompt to your packaged output

  • run HTML5LaunchHelper.exe or python -m SimpleHTTPServer 8000 (again, from the where the packaged files are created)

  • open your browser to http://localhost:8000

  • open the developer tools via: Control+Shift+I (as in "eye")

  • click on the Console tab in the developer tools window

  • back in the browser, click on CPP_FP.html

  • wait for the game to finish loading up

  • in the console tab -- you should see foo printed in there, this will correspond to the C++ to JS call you will see at the end of ACPP_FPCharacter::BeginPlay() in CPP_FPCharacter.cpp

  • in the console tab, type the following:

  • MyProject_JSLibs.call_HTML5_to_UE4_function()

  • after pressing enter (which will demonstrate a JS to C++ call) -- in the game (browser), you should see the character shoot a single round

i hope this is a clear example of your question.

you can diff the files before copying the zipped files to see what edits were needed to make this all work.

cpp-fp.zip (6.8 kB)
avatar image timg_razer Jul 30 '19 at 12:36 AM

I looked over your sample files. It's a similar setup to the HTML sample.

Are there any restrictions? For this to work does it have to be in Source/ folder or can it also work in Plugins/ folder?

avatar image nick.shin STAFF Jul 30 '19 at 02:13 AM

yes, this concept will work for Plugins.

for restrictions, take a look at: Engine/Plugins/Experimental/HTML5Networking/

  • HTML5Networking.uplugin

  • Source/HTML5Networking/HTML5Networking.Build.cs

there, you will see an example of including a plugin that's used in HTML5:

  • in uplugin, you will see HTML5 whitelisted in the platforms list (this trips up a lot of developers when it comes to enabling the plugin for either favorite plugins -- sometimes, just sticking in your platform of choice might work out of the box)

  • and, in the Build.cs file, you can add the PublicAdditionalLibraries.Add(jsFilePath); line to include your custom JS file when the plugin is enabled

hope this helps!

avatar image timg_razer Jul 31 '19 at 05:44 AM

I made a sample repro project in 4.22. Here's a sample project that includes SampleHTML5.js, but it's not actually copying the file or the content to the HTML5 build folder even though I've whitelisted the platform. Shouldn't this work?

Here's a simple UE 4.22 project for testing JS: https://github.com/tgraupmann/UE4HTML5SampleSource

avatar image Aros_Prince Jul 31 '19 at 01:10 PM

What content?

Anyway it is not supposed to copy that js file to the output folder. It's a way to tell emscripten how to link your js and C++...

avatar image timg_razer Jul 31 '19 at 03:41 PM

I would expect that with this header: https://github.com/tgraupmann/UE4HTML5SampleSource/blob/master/Source/UE4HTML5SampleSource/SampleHTML5.h

If I invoke UE_InitSampleHTML5 it would invoke the JavaScript and log a message..

https://github.com/tgraupmann/UE4HTML5SampleSource/blob/master/Source/UE4HTML5SampleSource/SampleHTML5.js

Should the file content of SampleHTML5.js get copied into the build? Or is this a manual step? Or is the JS converted to C++ and put into the binary data?

I've noticed nothing can be found when I search for UE_InitSampleHTML5 in the build folder...

avatar image timg_razer Jul 31 '19 at 11:22 PM

The repro project is working. https://github.com/tgraupmann/UE4HTML5SampleSource

Once I added the sample level, button widget, blueprint library, and included the .h from the BP library, I saw the JS being included.

You can see when I click on the button widget, I can successfully invoke the JS method and it logs as expected.

alt text

avatar image Nybörjaren123 Jul 31 '19 at 11:42 PM

Reply to Nick Shin:

This seems to be the guide i was looking for on this particular problem. But i can't package or even launch a cpp-project so i need to solve that problem first. See https://answers.unrealengine.com/questions/854803/html5-launch-problem.html for more information on this common problem/bug?.

avatar image timg_razer Jul 31 '19 at 11:45 PM

Most likely you'll need to install Visual Studio 2017. You can also check out UE4 from source and run setup.cmd to get all the dependencies. You can continue to use the retail version after that. C++ projects should build if you do that. Feel free to try and run my sample project as a sanity check.

avatar image Nybörjaren123 Aug 01 '19 at 12:02 AM

yes, i have tried both visual studio 2017 and 2019. Tommorrow i try a clean vs 2017 install again. Sadly the documentation is sparse on installation of vs so this is the best source for information regarding installation https://www.youtube.com/watch?v=u1JCV3HNVwM . Let me know if you know any better/more recent tutorial regarding this. But the problem is not that it won't build, it just isn't loading in neither chrome 64 or firefox 64. Only BP projects packaged to html5 does. See this upload i did here to understand the problem: https://arcane-wildwood-26041.herokuapp.com

avatar image Nybörjaren123 Aug 08 '19 at 07:02 PM

If i wan't to pass parameters with my JS to C++ call, how do i edit this function?

In js-file: MyProject_setup_HTML5_to_UE4: function(cb) { // extern "C" MyProject_JSLibs.call_HTML5_to_UE4_function = function() { // callable JS function from JS dynCall('v', cb); } }, and in .header -file: void MyProject_setup_HTML5_to_UE4(void(*cb)());

So if i wan't to pass multiple string parameters, where do i type them?. Is there any documentation on this somewhere?.

Thanks in advance!

avatar image Nybörjaren123 Aug 01 '19 at 02:35 PM

Reply to Nick Shin 2:

Ok, so i solved the problem with html launch failing. Uninstalling datasmith solved it. Can you confirm that c++ project + datasmith to html is unsupported at this moment in 4.22?.

I then went ahead and tried the UE4HTML5SampleSource and it's working correctly. However, that is just one-way traffic in that example. So i then tried follow your guide and the step "unzip the attached zipfile and drop it in Source/." Under Source there is another folder called CPP_FP , is this where im supposed to put the zip-files?

Anyway, trying to package this i get an unknown symbol-error. And rebuilding the project in VS2017 i get this error:

2>CPP_FPCharacter.cpp.obj : error LNK2019: unresolved external symbol MyProject_from_UE4_to_HTML5 referenced in function "protected: virtual void __cdecl ACPP_FPCharacter::BeginPlay(void)" (?BeginPlay@ACPP_FPCharacter@@MEAAXXZ) 2>CPP_FPCharacter.cpp.obj : error LNK2019: unresolved external symbol MyProject_setup_HTML5_to_UE4 referenced in function "protected: virtual void __cdecl ACPP_FPCharacter::BeginPlay(void)" (?BeginPlay@ACPP_FPCharacter@@MEAAXXZ) 2>C:\Users\fredr\Documents\Unreal Projects\CPP_FP\Binaries\Win64\UE4Editor-CPP_FP.dll : fatal error LNK1120: 2 unresolved externals 2>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\Microsoft.MakeFile.Targets(49,5): error MSB3073: The command ""C:\Program Files\Epic Games\UE_4.22\Engine\Build\BatchFiles\Rebuild.bat" CPP_FPEditor Win64 Development -Project="C:\Users\fredr\Documents\Unreal Projects\CPP_FP\CPP_FP.uproject" -WaitMutex -FromMsBuild" exited with code -1. 2>Done building project "CPP_FP.vcxproj" -- FAILED.

**EDIT: Nevermind. Solved this problem aswell (overwrite all files in source/CPP_FP folder with your zip) and can now confirm that your guide is working perfectly!

Now im going to dig down into the code to figure out the steps taken ;)**

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
more ▼

answered Feb 15 '17 at 05:44 PM

avatar image

tgraupmann
112 16 23 81

avatar image Aros_Prince Jul 09 '19 at 01:53 PM

All of the links to github on this page are 404. Can anyone update the answer?

When I try to add my own js files to the build by editing the project.build.cs like this:

 if (Target.Platform == UnrealTargetPlatform.HTML5)
 {
     PublicAdditionalLibraries.Add("JSEvents.js");
 }

It tells me that the file doesn't exist, which is obviously because it searches for it in the Epic Games\UE_4.22\Engine\Source\ and not in the project folder...

Any ideas?

avatar image tgraupmann Jul 09 '19 at 03:42 PM

You need to link your Epic account with your Github Account in order to see the links.

avatar image Aros_Prince Jul 10 '19 at 07:27 AM

I did so, but it didn't help.

avatar image tgraupmann Jul 10 '19 at 03:47 PM
avatar image Aros_Prince Jul 11 '19 at 11:48 AM

OK, it works now. Thanks.

But it is still not clear how can I add my own JS function from outside of HTML5JavaScriptFx.js.

Now, I was able to add my own JS file to the build. But I just can't figure out how to define a handler like this one:

UE_RegisterCustomListener: function(listener) { UE_JSlib.UE_CustomEvent = function() { Runtime.dynCall('v', listener); } },

unless I put it directly in the HTML5JavaScriptFx.js, which does work. But I need to modify the engine files on all of the machines I want to use for building... Obviously it would be much nicer if I could define the function in one of my project files.

Any ideas?

avatar image Aros_Prince Aug 06 '19 at 06:47 AM

Just to conclude this issue here...

autoAddDeps and mergeInto functions are the way to get your own functions defined anywhere into the project so that they can be called from JS or your own JS functions to be called from your UE project C++ code.

avatar image timg_razer Aug 06 '19 at 02:40 PM

To complete the sample projects, I still need to add how to call Blueprint/C++ functions from JS. It looks like something like Module.ccall?

avatar image Aros_Prince Aug 07 '19 at 07:03 AM

No, not anymore. I think it used to be that way a long time ago, but now the integration is much further...

To call C++ function from JS you need to:

1) define the function that registers the callback in a JS file. In order to do that just add a JS file to your project and add it to the Build.cs (I think you already have that). The content of the file can be something like this:

 var JSEvents = {
     MyProject_RegisterStringFunction: function (listener) {
         MyProject_JSlib.UE_Update = function (str) {
             var cname = _malloc(str.length + 1);
             writeStringToMemory(str, cname);
             Runtime.dynCall('vi', listener, [cname]);
         }
     },
 
     $MyProject_JSlib: {
         test: function () {
             console.log('test JS function');
         }
     }
 };
 
 autoAddDeps(JSEvents, '$MyProject_JSlib');
 mergeInto(LibraryManager.library, JSEvents);

In this case, we have a callback function that takes a string as a parameter.

At this point we have a JS definition of the function. We still need to declare the function header in C++ to be able to call it from there:

2) Declare the register function:

Put the following declaration somewhere in your headers, in my case in JSEvents.h:

 extern "C" {    
     void MyProject_RegisterStringFunction(void(*listener)(const char* str));
 }

3) Now we just need to call the function from somewhere. It doesn't matter, put it in to some initialization code that is run when you start he app:

 #ifdef __EMSCRIPTEN__
     /* register the listener */
     MyProject_RegisterStringFunction(update);
 #endif

where update is a function with the following signature:

 void update(const char* str);

...of course the name doesn't matter :-)

And that's all. It's really that simple. The only problem is that it isn't documented anywhere. It would be nice to make a wiki article...

avatar image Nybörjaren123 Aug 08 '19 at 07:18 PM

I managed to get two-way communication up and running with Nick Shins demo.

I'm just lacking parameters.

This seem to be you passing a string parameter?.

I don't really understand this part:
"var cname = _malloc(str.length + 1); writeStringToMemory(str, cname); Runtime.dynCall('vi', listener, [cname]);"

And then the last part i dont really understand either. If i wan't to call it from a cpp what do i type instead? ;).

avatar image Aros_Prince 3 days ago

Yes, that's how you pass a string from JS to C++. As for the other way around... Sorry, I don't know. So far I didn't need it.

avatar image timg_razer Aug 10 '19 at 02:06 AM

Thanks for the example code.

I've added it to the sample project and now C++ to JS works both ways.

Works in source: https://github.com/tgraupmann/UE4HTML5SampleSource

Works as a plugin: https://github.com/tgraupmann/UE4HTML5SamplePlugin

avatar image Aros_Prince 3 days ago

Thanks for making the example for future generations... I wish it existed when I started with UE HTML5. This would have saved me weeks :-)

avatar image timg_razer Jul 28 '19 at 03:13 AM

I caught up to you.

The example listed works for a plugin inside the engine. But how do you make it work for a 3rd party plugin so that it can search to find your file.

I'm trying this.

public class UE4_Speech : ModuleRules
{
    public UE4_Speech(ReadOnlyTargetRules Target) : base(Target)
    {
        if (Target.Platform == UnrealTargetPlatform.HTML5)
        {
            PublicAdditionalLibraries.Add("Plugins/UE4_Speech/Source/UE4_Speech/Private/WebGLSpeechDetectionPlugin.js");
            PublicAdditionalLibraries.Add("Plugins/UE4_Speech/Source/UE4_Speech/Private/WebGLSpeechSynthesisPlugin.js");
        }

The error I get is.

Output: // The Module object: Our interface to the outside world. We import PackagingResults: Error: ENOENT: no such file or directory, open 'C:\Program Files\Epic Games\UE_4.21\Engine\Source\Plugins\UE4_Speech\Source\UE4_Speech\Private\WebGLSpeechDetectionPlugin.js'" | Error: ENOENT: no such file or directory, open 'C:\Program Files\Epic Games\UE_4.21\Engine\Source\Plugins\UE4_Speech\Source\UE4_Speech\Private\WebGLSpeechDetectionPlugin.js'

Like you said it's looking in program files and not in the project folder.

I could put together an absolute path in C#, but that doesn't seem like the best way to go.

There's also a uproject setting that says a plugin has content. I'll try that option...

avatar image timg_razer Jul 28 '19 at 04:11 AM

This compiled for HTML5. I used ModuleDirectory to get the full path to the JS to include. I don't actually see the file copied in the build HTML5 folder though...

 // Some copyright should be here...
 
 using UnrealBuildTool;
 
 public class UE4_Speech : ModuleRules
 {
     public UE4_Speech(ReadOnlyTargetRules Target) : base(Target)
     {
         if (Target.Platform == UnrealTargetPlatform.HTML5)
         {
             string path = System.IO.Path.Combine(ModuleDirectory, "Private/WebGLSpeechDetectionPlugin.js").Replace("\\", "/");
             System.Console.WriteLine("Include {0}", path);
             PublicAdditionalLibraries.Add(path);
 
             path = System.IO.Path.Combine(ModuleDirectory, "Private/WebGLSpeechSynthesisPlugin.js").Replace("\\", "/");
             System.Console.WriteLine("Include {0}", path);
             PublicAdditionalLibraries.Add(path);
         }


Logging shows the correct full path.

Include C:/Private/UE4_SpeechDemo/Plugins/UE4_Speech/Source/UE4_Speech/Private/WebGLSpeechDetectionPlugin.js

Include C:/Private/UE4_SpeechDemo/Plugins/UE4_Speech/Source/UE4_Speech/Private/WebGLSpeechSynthesisPlugin.js

avatar image timg_razer Jul 29 '19 at 01:30 AM

To make it work, did you include the plugin in a source build of the engine? It doesn't seem to include the JS files as a project plugin.

avatar image Aros_Prince Jul 30 '19 at 07:46 AM

I would gladly answer this, but I don't understand the question...

I use this code to add my custom JS file to the build:

 if (Target.Platform == UnrealTargetPlatform.HTML5) 
 {            
     string dir = Path.GetDirectoryName(Target.ProjectFile.ToString());
     Console.WriteLine("Build.cs::HTML5: " + dir + "\n");
             
     PublicAdditionalLibraries.Add(dir + "/Source/MyProject/JSEvents.js");            
 }
(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question