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

The repro project is working.

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.

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 HTML5 launch problem - Platform & Builds - Epic Developer Community Forums for more information on this common problem/bug?.

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.

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 C++ with BP #1 - Getting Started in Unreal Engine 4 ( UE4 ) - YouTube .
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

Both versions work in these sample projects.

HTML5 can be included from game source.

HTML5 can be included from a plugin.

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.

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\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\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 ;)**

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.

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?

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:

  1. 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));
}
  1. 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 :slight_smile:

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…

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!

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? ;).

Thanks for the example code.

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

Works in source:

Works as a plugin:

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.

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