Unreal.js

Hey, since 2 day’s im trying to run a js function emitted by an existing c++ actor.

I tried to create a c++ Actor with BlueprintImplementableEvent, i can use it in Blueprint.

Now, tried to create a subclass from that c++ Actor class and overwrite the function, no success.
Then i created a Blueprint that inherit from my c++ Actor, same not working yet.

I can see my function being called inside the blueprint, so i thought i could create a blueprint function and overwrite that to get the data inside unreal.js - no success either.

Should i use multicast delegate ? Can i implement these events in js ?

I’d love to see some workflow that allows to call a function in c++ and is being received in js via “me.on(“cpp_event”,() => …”

Heres some JS code…




         class UdpClient extends Blueprint.Load('/Game/UDP_B').GeneratedClass {
             constructor(){
                super();
            }
        ctor() {
            // Subobject initialization, property initialization
            this.bAlwaysRelevant = true
        }
          // THIS IS NOT WORKING
        MyFunc()
            console.log("INSIDE JS");
        }
          // FUNCTION THAT WORKS INSIDE BLUEPRINT, UNFORTUNATLY NOT FIRED HERE 
        MCEvent(actor) {
            console.log("****");
            return blax(actor);
            // return call_your_js_func(actor)
        }
        blax(a){
            console.log("**Y*Y*Y*Y*Y*Y*Y*");
         }
         }

        let MyActor_Cx = require('uclass')()(global,UdpClient)
        var blax = new MyActor_Cx(GWorld,{X:1});


@Flashback, unreal.js grabs all accessible classes during initialization, so your BP func library should be visible (loaded) before you create a javascript component.
@Apoctwist, I have tested with my macbook (updated to recent os, but I don’t remember its code name) but I had no problem with the marketplace version. Could you elaborate your problem?

Hi is Android supported? I get errors like when i try to launch on the device:

D:/UE4/UnrealEngine/Epic Games/4.13/Engine/Plugins/Marketplace/UnrealJS/ThirdParty/v8/lib/Android/ARMv7/libv8_base.a(code-stubs.o):code-stubs.cc:function std::__1::basic_ios<char, std::__1::char_traits<char> >::~basic_ios(): error: undefined reference to ‘std::__1::ios_base::~ios_base()’

Sanjit

I get the following error on my system when I try to launch Unreal 4.13.1 with eh plugin installed

Plugin ‘UnrealJS’ failed to load because module ‘V8’ could not be loaded. There may be an operating system error or the module may not be properly set up.

That’s when I install it directly from the marketplace. I’m on the latest version of El Capitan.

@Apoctwist I just found published mac osx build has problem with loading dylib’s. Until next release of unreal.js, you can hack with a workaround for this issue.

Hello I just have a simple question but I can’t find a way to do this (I think I have a problem with finding equivalent in JS).
i would like to change a Vector Parameter Value in a Material.

I’m using this function :

And the only thing I have in return is :

&stc=1

I’m sorry if this is kind of noobish but do you have any idea how I can do this?

Thanks a lot

You should create an MaterialInstanceDynamic. Instanced Materials in Unreal Engine | Unreal Engine 5.1 Documentation

let yourMID = yourMaterial.CreateDynamicMaterialInstance()
yourMID.SetVectorMaterialParameter(…)

Thanks for your answer nako_sung !
I did that but when I try to apply it to my actor I have the same error : (SetMaterial is not a function) here is my code :

Hi nako_sung
I still am unable to run the plugin on Android.

As per your suggestion I downloaded the Android libs from

and added the libs to UnrealEngine\Epic Games\4.13\Engine\Plugins\Marketplace\UnrealJS\ThirdParty\v8\lib\Android.

I then tried to launch on my Nexus5 but got numerous STL related compile errors. Looks like it cant find libsampler.lib . This is not there in the prebuilt android libs package.

So tried to compile V8 based on the wiki at V8 · ncsoft/Unreal.js Wiki · GitHub and I get these errors:

make[1]: Entering directory /d/unworld/V8/android/v8' GYP_GENERATORS=make-android \ GYP_DEFINES="target_arch=arm v8_target_arch=arm OS=android" \ PYTHONPATH="/d/unworld/V8/android/v8/tools/generate_shim_headers:/d/unworld/V8/android/v8/gypfiles:" \ tools/gyp/gyp --generator-output="out" gypfiles/all.gyp \ -Igypfiles/standalone.gypi --depth=. \ -S.android_arm.release -Dv8_enable_backtrace=1 -Dv8_use_snapshot='false' -Dv8_enable_i18n_support=0 -Darm_fpu=default -Darm_float_abi=default The system cannot find the path specified. gyp: Call to '/bin/echo -n ${HOME}/goma' returned exit status 1 while in gypfiles\all.gyp. make[1]: *** [out/Makefile.android_arm.release] Error 1 make[1]: Leaving directory /d/unworld/V8/android/v8’
make: *** [android_arm.release] Error 2

Any suggestions ?
Thanks for the help!

Sanjit

Hi,

I just played around with UnrealJS and its awesome so far. I want to create a script where I have access to everything witihin a blueprint (vars, functions, …) and call them directly from JS. But I don’t want to extend the Blueprint itself through JS. This is because I need to create an actor or another blueprint to run this code. I just want to add the script to a blueprint and then use all of the data there. Same for overriding functions.

Currently I’m trying someting like this:

BP_JSTest
int val;

BP_JSTest1
Added JSComponent with class: BP_JSTest1 extends Blueprint.Load("/Game/BP_JSTest").GeneratedClass {}

var BP_JSTest1_C = require(“uclass”)()(global, BP_JSTest1);
var actor=new BP_JSTest1_C();

The problem here is that I have already assigned the script to a blueprint but then need to create a new actor to execute the blueprint itself. Even if I add the script to an empty
Actor within the world it would create a new actor what I want to avoid.

Is there a possiblity to just extend a blueprint with a JS Script Component and have access to all of its data / functions / vars?

I understand why I have to create the new actor because of the new blueprint class. My concern is here that I have always to create a dummy Actor which is then abandoned and useless (as far as I know).

Any suggestions?
Thanks for the help!

freakxnet

As far as I understand, you are willing to add a javascript component which accesses only owner actor, and setting some delegates on it. First of all, it is not desirable to have multiple javascript components for your application, because every javascript components create its own V8 instances(isolate/context). Instead you could create a javascript script component which is telling ‘main javascript component’ to invoke some entry js file for its owner actor.

UJavascriptScriptComponent::BeginPlay() {
auto JSComp = FindTheJavascriptComponentInYourWorld();
auto EntryPoint = this->EntryPoint; // FString UPROPERTY
JSComp->RunScript( *FString::Printf(TEXT(“run_script(%s,%s)”), *Owner->GetName(), *EntryPoint );
}

UJavascriptScriptComponent::EndPlay() {

JSComp->RunScript( …(“finish_script(%s,%s)”) … );
}

In your .js:

let running_scripts = {}
function run_script(actor_name, entry) {
let actor = GWorld.FindActorByName/I don’t remember the exact function name/(actor_name)
let script = require(entry)
running_script[actor_name] = script(actor) // run!
}

function finish_script(actor_name) {
running_scriptactor_name // invoke terminator!
delete running_script
}

// in your entry.js
module.exports = function (actor) {
console.log('Hello actor ${actor.GetName()}) return function () { console.log(bye ${actor.GetName()}`)
}
}

Thank you for your fast response!

Oh ok. So then I “used” it wrong so far. If there is for each JS Component a new V8 instanced forked than this is surely a problem. Thank you for the code snippet I will take a deeper look into it.

Kind regards

freakxnet

@dsanjit In fact prebuilt binaries for android was built by @marynate. Could @marynate help this problem? :slight_smile:

Hi Nako_sung, I’m a bit new to JavaScript in this form (or any form other than HTML snippets). Can you tell me if I can use node.js with your plugin. In my case I’ve found a bit of js on GitHub where someone is accessing a blackmagic deck link card - a video capture/playback device - and is able to deliver frames in node.js buffers. I want to be able to use this video feed on textures in my game. What do you think? (The link is macadam/README.md at master · Streampunk/macadam · GitHub)

It’s the kind of thing that should be achievable using a c++ plugin - there’s an sdk for the card - but my c++ is even worse than my JavaScript.

Thanks!

Ahh - actually, you told me almost a year ago that node.js isn’t supported. I’ll find a way! cheers.

I’m curious if you’ve investigated the possibility of embracing currently unsupported platforms (iOS and current-gen consoles). It is possible to use web view and built-in JS engine there to replace V8?

Unreal.js looks like a brilliant PoC at the moment, but desktop lock-up that promises nothing but total C++ rewrite may be a huge turn-off for most projects.

@anonymous_user_30094cfa Yes. It is possible to modify unreal.js to be decoupled from V8. But for now I don’t have a plan to code for other platforms. Volunteers needed! :slight_smile:

Ok, I’m back to Unreal-ing after surviving another deadline, and would still like to resolve this:

@nako_sung, this makes sense, but I don’t see what I’m doing wrong, as it doesn’t work. I create my blueprint library like this:

1.png

…and trigger the code that creates JS context much later (say, on key press). It should satisfy the condition you mentioned, right? But it doesn’t. Do I have some wrong assumptions about BP-defined blueprint libraries’ lifespan? How does one make it visible (loaded), or at what point Unreal loads it? Why can level blueprint call a function from FbLib on BeginPlay, but JS context can’t call it 5 seconds later (but at the same time it can call a function from BP library defined in C++)?

P.S.: On unrelated note, the launcher told me yesterday that Unreal.js is incompatible with 4.14. But it will be in the nearest future, right? =)

@Flashback I just tested BPFuncLib without any errors. You should use class name with suffix _C. (Actually YourBP.GeneratedClass or Blueprint.Load(YourBP-path).GeneratedClass)

  1. Create a new BPFuncLib (NewFunctionLibrary)
  2. Add a method (test)
  3. Launch a new game
  4. Open JavascriptLogConsole / NewFunctionLibrary_C.test()

Unreal.js for 4.14 is available on github. I’ll submit 4.14 updated version soon. :slight_smile:

(naive) Support for Map/Set has been added. :slight_smile: