Unity 開発者向け Wonderland Engine

このページでは、Unity から Wonderland Engine へのスクリプティングのマッピングを紹介し、ソリューション構築のための違いをリストアップします。

ビデオ形式を好む場合は、YouTube チャンネルの切り替えガイドをチェックしてみてください。

YouTube Video

スクリプティング 

Wonderland Engine はブラウザ上で動作し、JavaScript ランタイムが組み込まれています。これは Web エンジンのスクリプティング言語として最適な選択であり、追加ダウンロードを必要としません。

スクリプトを作成するには、Wonderland Editor のアセットブラウザで右クリックし、新しい JavaScript / TypeScript コンポーネントを作成します。基本的なテンプレートが含まれていますので、すぐに始められます。

JS/TS に適した IDE は Visual Studio Code です。

Wonderland Engine の API と Unity の違いについては、コードセクションをご覧ください。

TypeScript vs JavaScript 

TypeScript は JavaScript に静的型チェックを追加し、C# に非常に近づけます。これにより、IDE のコード補完が大幅に向上します。Unity に慣れた開発者には TypeScript を推奨します。

Wonderland Engine は tsconfig.json の設定を自動的に行います。アセットブラウザから TypeScript コンポーネントを作成するだけで動作します。

パッケージング 

Unity のワークフローでは通常、エディタ内のプレビューが使用されますが、Wonderland Engine ではパッケージングが非常に速いため、ブラウザ内での最終アプリをプレビューとして使用することができます。

パッケージをリロードするたびにページがブラウザで更新されます。Views > Preferences で「Force full page reloads」を無効にすることで、さらに速いライブリロードサイクルを実現することが可能です。

アプリケーションをデプロイするには、プロジェクトの deploy フォルダの内容をウェブサーバーにアップロードするだけです。または、Views > Plugins でアクティベートできる “Wonderland Cloud Publish” プラグインを使用してアップロードすることも可能です。

複数のシーン 

Wonderland Engine では、multiple project files(.wlp) で作成された複数のシーンを切り替えることができます。シーン切り替えチュートリアルをご覧ください。

また、ランタイム中にシーンの一部をストリームすることも可能です。Streaming .bin Files チュートリアルをご覧ください。

プレハブ 

Wonderland Engine にはプレハブに相当する機能はまだありませんが、シーンでプロトタイプを設定し、object.clone() でその階層とすべてのコンポーネントを複製することができます。

あるいは、プレハブオブジェクトを別のシーンに移動し、ランタイム中に engine.loadPrefab(…) を使用してロードし、インスタンス化することができます。

アセットのインポート 

Wonderland Engine では、シーンファイルをインポートすると(アセットブラウザから Scene View または Scene Outline へドラッグ&ドロップするか、画像ファイルをマテリアルのテクスチャスロットにドラッグすることで)、リンクされ、変更が監視されます。シーンファイルで見つかったリソースはプロジェクト内で使用可能になり、「Resources」ビューで確認できます。

アセットブラウザからインポートされるまでは、プロジェクトで利用できません。「アセットブラウザ」は、Unity のものとは異なるファイルブラウザと考えられます。

アセットの最適化 

インポートされたアセットはさらに最適化されます:

  • メッシュは頂点数を削減するために自動デシメートが行われます
  • メッシュは均一にスケーリングできます
  • 画像は自動圧縮されます
  • 画像は縮小可能です

これらの設定は「Resources」ビューで行います。

ディレクトリ 

  • deploy にはパッケージングの最終結果が含まれています。
  • static には、そのままデプロイされるファイルが含まれています。
  • cache はキャッシュされたアセットコンパイル結果を含みます。通常、削除しても問題ありませんが、再生成には時間がかかります。

これらの設定は「Resources」ビューで行います。

アニメーション 

アニメーションは animation コンポーネントタイプを使用して再生されます。スキンアニメーションは、retarget チェックボックスを使ってターゲットスキンの骨/ジョイントの1つにコンポーネントをアタッチする必要があります。

キーフレーム編集および「Custom Event」キーフレームは Animation Editor でサポートされています(Views > Animation Editor を参照)。トラックブレンディングはまだサポートされていません。

物理演算 

リジッドボディは physx コンポーネントタイプを使用して作成されます。シーンはエディタ内で Debug > Simulate Physics (Shift + Alt + S) を使用してシミュレーションできます。

ネットワーキング 

ピアツーピアネットワーキングは、コミュニティサポートによる Wonderland Engine PeerJS Networking で実現可能です。

WebRTC を使用し、規模に応じてデフォルトの PeerJS サーバーインフラを利用できます。

また、コミュニティはマルチユーザーのために Colyseus を統合しています。

UI 

ユーザーインターフェースは、cursorcursor-target、および collider コンポーネントを使用して手動でセットアップされます。

以下の HTML5 Canvas ベースの 2D UI はコミュニティによって維持されています:Lazy Widgets project

用語 

用語UnityWonderland Engine
プロジェクトプロジェクトファイル複数のプロジェクトファイルが単一のプロジェクトルートディレクトリを共有する可能性あり
インスペクタビュープロパティビュー

コード 

以下に一般的なコードパターンと、Wonderland Engine での対応例を示します。

カスタムビヘイビア 

Wonderland Engine では「MonoBehaviour」の代わりに「Component」を使用します。これを書くには、Component クラスを拡張します:

Unity Wonderland Engine (JavaScript) Wonderland Engine (TypeScript)
using UnityEngine;
using System.Collections;

public class MainPlayer : MonoBehaviour
{
  [field: SerializeField]
  public string myName;

  string privateName;

  void Start()
  {
    Debug.Log("My name is", this.myName, this.privateName);
  }

  void Update()
  {
    Debug.Log("Delta time:", Time.deltaTime);
  }
}
import {Component, Property} from '@wonderlandengine/api';

export class MainPlayer extends Component {
    static TypeName = 'main-player';

    /* プロパティはエディタで公開されます */
    static Properties = {
        myName: Property.string('Alice'),
    };

    privateName = 'Bob';

    start() {
        console.log('My name is', this.myName, this.privateName);
    }

    update(dt) {
        console.log('Delta time:', dt);
    }
}
import {Component} from '@wonderlandengine/api';
import {property} from '@wonderlandengine/api/decorators.js';

export class MainPlayer extends Component {
    static TypeName = 'main-player';

    /* プロパティはエディタで公開されます */
    @property.string('Alice')
    myName!: string;

    privateName = 'Bob';

    start() {
        console.log('My name is', this.myName, this.privateName);
    }

    update(dt: number) {
        console.log('Delta time:', dt);
    }
}

Unity と同様に、いくつかの UI 要素がパラメータのために生成されます。

ゲームオブジェクトにあるコンポーネントを取得 

Unity Wonderland Engine
gameObject.GetComponent<MyComponent>();
// 推奨される方法、型が推論されるため
this.object.getComponent(MyComponent);

// または: 型名で指定
this.object.getComponent('my-component');

オブジェクトにコンポーネントを追加 

Unity Wonderland Engine
MyComponent sc = gameObject.AddComponent<MyComponent>();
sc.property = "set";
this.object.addComponent(MyComponent, {property: 'set'});

// または: 型名で指定
this.object.addComponent('my-component', {property: 'set'});

// または: アクティベーションを遅延
const sc = this.object.addComponent('my-component', {active: false});
sc.property = 'set';
sc.active = true;

子オブジェクトを取得 

Unity Wonderland Engine

gameObject.transform.GetChild(0);
this.object.children[0];

親オブジェクトを取得 

Unity Wonderland Engine
gameObject.transform.parent
this.object.parent;

マテリアルプロパティを設定 

色やテクスチャなどのマテリアルプロパティを設定します。

Unity Wonderland Engine
var mesh = gameObject.GetComponent<MeshRenderer>();
mesh.material.SetColor("_Color", Color.green);
const mesh = this.object.getComponent(MeshComponent);
mesh.material.setDiffuseColor([0.0, 1.0, 0.0, 1.0]);

数学 

JavaScript は operator overloading をサポートしていないため、数学コードに対するアプローチが異なります。

多くの場合、Wonderland Engine の Object3D API には変換を操作するための多くの関数があり、WebAssembly で効率的に実装されています:

/* オブジェクトを複数の軸に沿って移動します。ベクトルのために一時的なメンバーまたはモジュールスコープ内の定数を使用してください。 */
this.object.translateWorld([1, 2, 3]);

/* Y 軸を中心にオブジェクトを回転します。 */
const AxisY = [0, 1, 0];
this.object.rotateAxisAngleDegLocal(AxisY, 25);

ガベージコレクション 

JavaScript はガベージ収集を行う言語であり、自動ガベージコレクションによる計画外の中断が発生する可能性があります。そのため、メモリにリスト/ベクトルやオブジェクトを追加することを避けるのが最適です。

カスタムコンポーネントのコンストラクタ内またはボディ内で、一時的なベクトルやクォータニオンを作成し再利用するか、あるいは慎重に使用する場合は、モジュールスコープ内にそれらを置くことをお勧めします(クラスの上に)。[0, 1, 0] のような定数ベクトルは、モジュールスコープに const AxisY = [0, 1, 0] として宣言します。

数学ライブラリ 

JavaScript/TypeScript 用の性能とガベージコレクションに配慮した数学ライブラリ glMatrix の使用をお勧めします。これはデフォルトのテンプレートおよびコンポーネントにすでにインストールされているため、自分でインストールする必要はありません。

glMatrix が計算するベクトルやクォータニオンは、新たに割り当てられたベクトルを返さず、最初のパラメータとして結果を格納する場所を指定してください。プリミティブを返す関数は通常通り結果を返します。

glMatrix 数学ライブラリの完全なドキュメントはこちらを参照してください。

Unity Wonderland Engine
var v = new Vector3(1, 2, 3);
v.Set(3, 2, 1);
const v = vec3.fromValues(1, 2, 3);
vec3.set(v, 3, 2, 1);
var a = new Vector3(1, 2, 3);
var b = new Vector3(1, 2, 3);

var v = a + b;
var a = a * b;
var a = 2.0*a;
import {vec3} from 'gl-matrix';

const a = vec3.fromValues(1, 2, 3);
const b = vec3.fromValues(1, 2, 3);

const v = vec3.add(vec3.create(), a, b);
vec3.mul(a, a, b);
vec3.scale(a, a, 2.0);

JavaScript vs C# 

C# から移行する際の特徴的な違いは以下の通りです:

  • メンバー変数へアクセスする際は常に this. をプレフィックスにします。
  • var は「グローバル」を作成し、現在のスコープに制限されません。最良の方法は let または const を使用してスコープ付き変数を作成することです。