Unreal.js icon indicating copy to clipboard operation
Unreal.js copied to clipboard

Can I define new blueprint types that I can create in the editor?

Open TheBunyip opened this issue 9 years ago • 8 comments

I'm wanting to add a new 'class' to my game by defining it in JavaScript and then being able to add new instances of it in the normal way in the Unreal Editor...

image

Is this possible using Unreal.js?

TheBunyip avatar Jan 30 '17 12:01 TheBunyip

Although it is not possible to declare BP-accessible types in Unreal.js, you can use 'factory pattern' to instantiate javascript class in BP instead.

nakosung avatar Jan 31 '17 09:01 nakosung

Ok, thanks.

TheBunyip avatar Jan 31 '17 10:01 TheBunyip

Is there any documentation or a sample that demonstrates how to instantiate a JS object from a Blueprint?

TheBunyip avatar Jan 31 '17 11:01 TheBunyip

There is no publicly available resources demonstrating this pattern.

  1. Declare factory method in your base BP (like PlayerController, ...)
  2. Inherit that class in JS and set it as a default class to use by game engine. (https://github.com/ncsoft/Unreal.js/blob/master/Examples/Content/Scripts/helloInputBinding.js#L37)
let factory = {}
class MyPlayerController extends PlayerController {
  /* string, string -> UObject */
  YourFactoryMethod(type,arg) { 
    let fac =factory[type]
    return fac ? fac(arg) : null
  }
}
function register(type,klass) {
  let uclass = require('uclass')()(global,klass)
  factory[type] = (arg) => { let x = new uclass(GWorld); x.init(arg); return x }
}

class MyJS_BP extends Actor {
  BeginPlay() {
    super.BeginPlay()
    // this is experimental (I haven't tested yet)
    this.jsref.Ref = this
  }
  EndPlay() {
    super.EndPlay()
    this.jsref.Ref = null
  }
  properties {
    this.jsref /*JavascriptObject */
  }
  init(arg) {
    console.log(arg)
  }
}

let MyPC_C = require('uclass')()(global,MyPlayerController)
GWorld.GetGameMode().PlayerControllerClass = MyPC_C

register("TypeA", MyJS_BP )

nakosung avatar Jan 31 '17 21:01 nakosung

Great I'll give that a try. Thankyou.

On 31 Jan 2017 21:52, "Nako Sung" [email protected] wrote:

There is no publicly available resources demonstrating this pattern.

  1. Declare factory method in your base BP (like PlayerController, ...)
  2. Inherit that class in JS and set it as a default class to use by game engine. (https://github.com/ncsoft/Unreal.js/blob/master/ Examples/Content/Scripts/helloInputBinding.js#L37 https://github.com/ncsoft/Unreal.js/blob/master/Examples/Content/Scripts/helloInputBinding.js#L37 )

let factory = {}class YourPC extends PlayerController { /* string, string -> UObject */ YourFactoryMethod(type,arg) { let fac =factory[type] return fac ? fac(arg) : null } } class MyJS_BP extends Actor { BeginPlay() { super.BeginPlay() // this is experimental (I haven't tested yet) this.jsref = this } EndPlay() { super.EndPlay() this.jsref = null } properties { this.jsref /*JavascriptObject */ } }

factory["TypeA"] = (arg) => { let x = new MyJS_BP(); x.init(arg); return x }

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ncsoft/Unreal.js/issues/141#issuecomment-276504610, or mute the thread https://github.com/notifications/unsubscribe-auth/AAItGIKVyo_2KdX5EX57P4oYYlWQTkNrks5rX60ugaJpZM4LxXN2 .

TheBunyip avatar Jan 31 '17 22:01 TheBunyip

One final thing - how do I make sure the JS file containing my factory method is loaded into Unreal before a blueprint accesses it?

On 31 Jan 2017 22:52, "Ben M" [email protected] wrote:

Great I'll give that a try. Thankyou.

On 31 Jan 2017 21:52, "Nako Sung" [email protected] wrote:

There is no publicly available resources demonstrating this pattern.

  1. Declare factory method in your base BP (like PlayerController, ...)
  2. Inherit that class in JS and set it as a default class to use by game engine. (https://github.com/ncsoft/Unreal.js/blob/master/Examples/ Content/Scripts/helloInputBinding.js#L37 https://github.com/ncsoft/Unreal.js/blob/master/Examples/Content/Scripts/helloInputBinding.js#L37 )

let factory = {}class YourPC extends PlayerController { /* string, string -> UObject */ YourFactoryMethod(type,arg) { let fac =factory[type] return fac ? fac(arg) : null } } class MyJS_BP extends Actor { BeginPlay() { super.BeginPlay() // this is experimental (I haven't tested yet) this.jsref = this } EndPlay() { super.EndPlay() this.jsref = null } properties { this.jsref /*JavascriptObject */ } }

factory["TypeA"] = (arg) => { let x = new MyJS_BP(); x.init(arg); return x }

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ncsoft/Unreal.js/issues/141#issuecomment-276504610, or mute the thread https://github.com/notifications/unsubscribe-auth/AAItGIKVyo_2KdX5EX57P4oYYlWQTkNrks5rX60ugaJpZM4LxXN2 .

TheBunyip avatar Jan 31 '17 23:01 TheBunyip

@TheBunyip have you figured out how to do that? @nakosung can you help perhaps? I am interested in this too.

danielkcz avatar Mar 05 '17 09:03 danielkcz

Does this work? Can this be done for other objects aswell? For example, I want to edit my level, visually adding "coins", "ammo" or "enemies" not just swapping the default PlayerController class. Can this be achieved with the GameMode approach?

hiperbou avatar Jan 22 '18 15:01 hiperbou