Edited at

[UE4]Unreal.jsでJSのコードに型とフラグ情報を付与する

More than 1 year has passed since last update.

Unreal.jsプラグインでJavaScriptで作成したものをUE4の世界に認識させるには次の方法が必要になる。


  1. ES2015(ES6)の書き方でクラスを生成

  2. クラス・メソッド・プロパティに 型とフラグの情報を付与


  3. uclass.jsで型とフラグ情報を解析させてUE4側にクラスを認識させる

この「型とフラグの情報を付与」という部分が若干特殊なので説明。


Unreal.jsでの型およびフラグ情報の独自表現

周知の通り、JavaScriptには型表現の方法が基本的にない。一方UE4のUnreal C++ & Blueprintには型がある。Unreal.jsではこの差を埋めるために、コメント中に埋め込まれた型とフラグ情報を解析した上でUE4側に渡す形になっている。

また、Unreal C++独自のマクロ(UPROPERTYなど)での識別子指定もフラグ情報等として表現できる( メタデータ識別子 メタプロパティも一部対応しているようだ)。

以下が、それぞれのUnreal C++マクロに対応するJS側での書き方。


UCLASS


unreal_c++

UCLASS([specifier, specifier, ...], [meta(key=value, key=value, ...)])

class ClassName : public ParentName
{
GENERATED_BODY()
}

class ClassName /* ClassFlag+ClassFlag+... */ extends ParentClass {

ctor() {
// initialization
// component setup
}
properties() {
// property-declarations
}
}

class クラス名 /* フラグ情報1+フラグ情報2+... */ {}の形で定義する。

注意点:


  • ES5以前の疑似クラス定義には非対応


    • 文字列解析で処理されているため



  • コンストラクタはctor()


    • ES2015のconstructor()はJS側のコンストラクタ、ctor()はUE4側のコンストラクタとして働く



  • プロパティ(UPROPERTY)はproperties()で定義


  • UClassとして扱うには最後にuclass.jsで解析する必要がある

//transformed into corresponding USTRUCT and UCLASS

let cls = require('uclass')()(global, ClassName);

参考:USTRUCT and UCLASS


UFUNCTION


unreal_c++

UFUNCTION([specifier, specifier, ...], [meta(key=value, key=value, ...)])

ReturnType FunctionName([Parameter, Parameter, ...])

class ClassName{

//...
FunctionName([
Parameter /* PropertyFlag+ParamType */,
Parameter /* PropertyFlag+ParamType */,
...
]) /* specifier+ReturnType */
}

前提としてUCLASSと同時に定義する必要がある(JS的には必ずクラスのメソッド)。

関数名(引数名 /* UPROPERTYのフラグ+引数の型 */) /* UFUNCIONのフラグ+返り値の型 */という形で定義する。「UFUNCIONのフラグ」は関数指定子ということで調べられるが、Unreal.jsのWikiには言及がないのですべて使えるかどうかは不明。


UPROPERTY


unreal_c++

UPROPERTY([specifier, specifier, ...], [meta(key=value, key=value, ...)])

Type VariableName;


Unreal.js

class MyClassName{

//...
properties(){
this.VariableName /* specifier+specifier+...+Type */;
}
}

前提としてUSTRUCTUCLASSと同時に定義する必要がある。

UPROPERTYマクロは変数プロパティをエディタ上やBlueprint上から扱えるように設定するため設定する頻度が高い。JSで同様にするためにはproperties()メソッドの中で次のように定義する。properties()メソッド以外では定義できないので注意。

this.プロパティ名 /* フラグ1+フラグ2+...+型 */;

なお、ドキュメントには明記されていないがEditConditionなどのメタプロパティも次のような書き方で有効になった。


metaの書き方

properties() {

//bEditConditionが有効ならエディタ上で編集可能に
this.EditConditionVariable /* EditAnywhere+Category:condition+EditCondition:bEditCondition+int32*/
//エディタ上で普段は隠しておく
this.bEditCondition /* EditAnywhere+Category:condition+AdvancedDisplay+bool */;
}

MetaEditCondition1.png



MetaEditCondition2.png


USTRUCT


unreal_c++


USTRUCT([Specifier, Specifier, ...])
struct StructName
{
GENERATED_USTRUCT_BODY()
};

class StructName /* Struct+Specifier+Specifier+... */{

properties() {
//property-declarations
}
}

UStructはJSのクラスを作成したうえで、Structとコメントの最初に記述する。

参考:USTRUCT and UCLASS


補足情報


  • uclass.jsの中では正規表現で文字列解析して変換している



    • Function.toString()でソース文字列を引っ張って解析(コメントも取得できる)

    • なのでここのコードを書き換えるか同様の処理を別のJSでやれば別の記法で型とフラグ情報を付与できる




  • UINTERFACEマクロに相当するものはないっぽい?