LoginSignup
0

More than 5 years have passed since last update.

【PlayCanvas】無理やりWebWorkerを使ってマルチスレッド化する

Posted at

不完全ですがPlayCanvas上でWebWorker使ってマルチスレッド化を実現してみます

やり方

postmessage側とonmessage側のスクリプトをそれぞれ作ります。
postmessage側はPlayCanvasのスクリプトで作成し、適当なエンティティにアタッチしてinitializeに記述します
onmessage側はPlayCanvasスクリプトである必要はありません。

postmessage側

以下スクリプト作成し適当なエンティティにアタッチします

web-worker-test.js
var Webworkertest = pc.createScript('webWorkerTest');

Webworkertest.prototype.initialize = function() {

    if(window.Worker) {
        var workerfile;
        workerfile = this.app.assets.find("recive.js");

        this.worker = new Worker(workerfile.getFileUrl());

        this.worker.onmessage = function(e) {
            var result = e.data;
            console.log("from worker: " + result);
        };
        this.worker.onerror = function(e) {
            console.log(e);
        };
        var data = {
            name: "hello",
            age: 19
        };

        this.worker.postMessage(data);
    }
};

Webworkertest.prototype.update = function(dt) {

};

PlayCanvasのpc.Assets.find()メソッドで呼び出して、Worker()にgetFileUrl()メソッドで渡してあげるところがミソです。

onmessage側

recive.js
onmessage = function(e) {
    console.log(e.data);
};

シンプルにコンソール出力のみです。
こちらはアタッチする必要はありません。

実行

image.png

実行すると正しくrecive.jsのonmessageが動いていることが確認できます。

問題

現状Web Workerは"スクリプトファイル単位"で"同一ドメイン"が前提なため、ここから先動かすためにはちょっと問題があります。

ファイル圧縮すると動かない

ビルド時にConcatenate Scriptsにチェックを入れてビルドすると、内部のスクリプトファイルがすべて圧縮され__game-script.jsという名前に変更されてしまうため、正しく参照されなくなってしまいます

playcanv.asだとアセットファイルはCDNにあるため動かない

PlayCanvas上でデプロイするとindex.htmlはplaycanv.as上、アセットファイルはAmazon S3のEUリージョンにデプロイされます。
image.png
この状態ではクロスドメインなので当然Workerで呼び出すことはできません。

self hostでクロスドメインにならないような構成に変えてあげれば正しく動作します。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0