Unreal.js

Trying to get the editor extension example working - how to I get it to run? I tried attaching to actor, but that doesn’t seem to work (not sure why it would).

Also can this be used to make plugins that could be sold on the marketplace?

Where is the actual installation instruction? Can’t find it.

@nako_sung – just a quick question, could I use the web-socket support inside of Unreal.js to talk to a web-socket enabled web-based application either outside of Unreal or inside of Unreal using the UMG Web Browser Widget?

@qdelpeche Yes. you can use websocket but its api is not compatible with web browsers. (currently websocket is only available in windows platform)

@nako_sung - Very amazing work. Related to the concept of compatibility with web browsers, is there any planned added support for live JS interaction with HTML5 exported builds? This would be amazing.

Thanks for your hard work!

@a1programmer For now I have no plan for supporting HTML5, but it seems promising. :slight_smile:

I am trying to use this awesome plugin with UE4.13 Preview 3. I get these compile errors:

…Plugins/UnrealJS/Source/JavascriptWebSocket/JavascriptWebSocket.h(23): error : UFUNCTION inside this preprocessor block will be skipped
…Plugins/UnrealJS/Source/JavascriptWebSocket/JavascriptWebSocketServer.h(20): error : UFUNCTION inside this preprocessor block will be skipped

Any Suggestions ?

Thanks.

@dsanjit Support for 4.13 is updated. :slight_smile:

Thanks @nako_sung ! Works like a charm !

How do I do a line trace by channel in Unreal.JS? I keep getting “Error: Should write into array by passing an array instance”. Here is my code:

Required var type of 5th parameter is const TArray<AActor*>& ActorsToIngore. So you should pass [this] instead of this. :slight_smile:

@nako_sung. Ah, yep that fixes it. Thank you very much. I also had an error when calculating the tempEndTrace. The final code for single line trace is:

Is there anyway to access the FMath library inside of javascript? Running a code similar to


FMath::Rand()

.

@kelfire you have Math.random(), it is a native js-function. :slight_smile: If you want some more, you can grab some nice js modules via npm. For example there is nice scientific math library available (GitHub - numjs/numjs: NumJS Library is made for scientific computing in Javascript).

Arithmetic operations should be kept in pure js in order to achieve good performance. :slight_smile:

Yep, I was using some of the Math javascript functions. I thought it might be faster to switch to the Unreal C++ math. I didn’t know it is actually faster to use javascript math functions. The numjs library looks really good, I’ll book mark it future. Thank you.

@kelfire Calling BP from JS, or JS from BP cannot be optimized by V8. :slight_smile:

Is it possible to have 2 custom classes that know each other? In the code below, I created 2 custom actors. The first actor is a sword that has an owner of type myHero. The second actor is myHero with a variable of mySword. If I compile the mySword then myHero, I get this error


Warning: Failed to find object 'Object None.myHero'

. I can switch the compile order around but I would get this error


Warning: Failed to find object 'Object None.mySword'

. I know it is possible to write code like that in C++, but is it possible to write a similar code in Javascript?


class mySword extends Actor
{
    properties()
    {
        this.SwordInt /*EditAnywhere+int*/
        this.myOwner /*EditAnywhere+myHero*/
    }

    //overload Event Begin Play
    ReceiveBeginPlay()
    {

    }

    printMyText() /*BlueprintCallable*/
    {
        //print a text to the screen
        GWorld.PrintText("Sword: Printing Message", true, false, LinearColor.MakeColor(0,0,1,1), 3)
    }    
}

class myHero extends Actor
{
    properties()
    {
        this.heroInt /*EditAnywhere+int*/
        this.mySword /*EditAnywhere+mySword*/
    }

    //overload Event Begin Play
    ReceiveBeginPlay()
    {
        let sampleSword = new mySword_C(GWorld)
        this.mySword = sampleSword
        //this.mySword.printMyText()
        //this.mySword.myOwner = this
    }

    printMyText() /*BlueprintCallable*/
    {
        //print a text to the screen
        GWorld.PrintText("Hero: Printing Message", true, false, LinearColor.MakeColor(0,0,1,1), 3)
    }
}

let mySword_C = require('uclass')()(global, mySword) 
//compile myTimeActor
let myHero_C = require('uclass')()(global, myHero) 


//create an actor into the world, can fail if collide at spawn point
let myActor = new myHero_C(GWorld, Vector.MakeVector(0, 0, 10))


//need aliases.js for SetTimerbyFunctionName to be recognized
Context.RunFile('aliases.js')

Ok, I run the code inside the main function (hotReload_Init) and both custom actors were able to detect each other. The error message is still there, but it works. what is the difference between running the


new myHero_C(GWorld)

inside the main function instead of outside.


/// <reference path="typings/ue.d.ts">/>

/*
    Description: Create an 2 custom actors that depend on each other
    Detail: Implemented using Unreal Framework

*/

class mySword extends Actor
{
    properties()
    {
        this.SwordInt /*EditAnywhere+int*/
        this.myOwner /*EditAnywhere+myHero*/
    }

    //overload Event Begin Play
    ReceiveBeginPlay()
    {

    }

    printMyText() /*BlueprintCallable*/
    {
        //print a text to the screen
        GWorld.PrintText("Sword: Printing Message", true, false, LinearColor.MakeColor(0,0,1,1), 3)
    }    
}

class myHero extends Actor
{
    properties()
    {
        this.heroInt /*EditAnywhere+int*/
        this.myOwnSword /*EditAnywhere+mySword*/
    }

    //overload Event Begin Play
    ReceiveBeginPlay()
    {
        let sampleSword = new mySword_C(GWorld)
        this.mySword = sampleSword
        //this.mySword.printMyText()
        //this.mySword.myOwner = this
    }

    printMyText() /*BlueprintCallable*/
    {
        //print a text to the screen
        GWorld.PrintText("Hero: Printing Message", true, false, LinearColor.MakeColor(0,0,1,1), 3)
    }
}

let myHero_C = require('uclass')()(global, myHero) 
let mySword_C = require('uclass')()(global, mySword) 
//compile myTimeActor

function hotReload_Init()
{      
    console.log("zDoubleInherit.js: Initialization")
    new myHero_C(GWorld)
}

//clean up function for hot reload 
function hotReload_CleanUp()
{
    console.log("I am cleanup for live reload")
}

// 1) bootstrap to initiate live-reloading dev env. 
try 
{
    module.exports = () => 
    {
        let cleanup = null

        // wait for map to be loaded. then run hotReload_Init() which spawn the MyThirdPerson character
        process.nextTick(() => cleanup = hotReload_Init());

        // live-reloadable function should return its cleanup function
        return () => hotReload_CleanUp()
    }
}
catch (e) 
{
    //if try code failed then load required java files
    require('bootstrap')('zDoubleInherit')
}    



Edit Nevermind. I can call an Blueprint Interface like any other event/function after doing DoesImplementInterface() check.

Original
How do you interact with a Blueprint Interface inside of Javascript? I am able to load a Blueprint Interface using Blueprint.Load() and detect if an Actor is implementing an Interface by using DoesImplementInterface(). I still don’t know how to send an interface message to an actor.

This plugin is very well done;
There’s some wizardry in there I didn’t even knew it was possible lol