PlayCanvasで動的に画像をフェッチしてレンダリングする方法

PlayCanvasで動的に画像をフェッチしてレンダリングする方法

こんにちは、チャリセです!
今回は、PlayCanvasを使って動的に画像をフェッチし、3Dオブジェクトにレンダリングする方法について詳しく解説していきます。この技術は、ゲーム内のテクスチャを動的に更新したり、ユーザー生成コンテンツを表示したりする際に非常に有用です。

コードの概要
今回紹介するコードは、「FetchImage」というスクリプトです。このスクリプトは、指定されたURLから画像をフェッチし、それを3Dオブジェクトのテクスチャとして適用します。さらに、プレイヤーとオブジェクトの距離に基づいて、画像のロードとレンダリングのタイミングを制御する機能も持っています。

■ コードの解説

  1. スクリプトの初期化
var FetchImage = pc.createScript('fetchImage');

FetchImage.attributes.add('url', { type: 'string' });
FetchImage.attributes.add('showDistance', { type: 'number', default: 8 });
FetchImage.attributes.add('MINumber', { type: 'number', title: "Mesh Instance Number" });

このセクションでは、FetchImageスクリプトを定義し、必要な属性を追加しています。

  • url: 画像のURLを指定します。
  • showDistance: 画像を表示する距離のしきい値を設定します。
  • MINumber: メッシュインスタンスの番号を指定します。

2. 初期化関数

FetchImage.prototype.initialize = function () {
    this.player = Player;
    this.nowRange = 0;
    let name = this.entity.name;
    let nameSprit = name.split('_');
    this.ObjectId = Number(nameSprit[1]);
    this.imageLoaded = false;
};

この関数では、スクリプトの初期設定を行います。プレイヤーオブジェクトの参照、現在の距離、オブジェクトIDの設定、画像ロードフラグの初期化などが行われています。

3. 更新関数

FetchImage.prototype.postUpdate = function () {
    if (this.imageLoaded == false) {
        let camPos = this.player.getPosition();
        this.nowRange = camPos.distance(this.entity.getPosition());
        if (this.nowRange <= this.showDistance) {
            this.startLoadImageRender();
        }
    }
};

この関数は、フレームごとに呼び出され、プレイヤーとオブジェクトの距離を計算します。距離が「showDistance」以下になったら、画像のロードとレンダリングを開始します。

4. 画像ロードとレンダリング関数

FetchImage.prototype.startLoadImageRender = function () {
    var self = this;
    let dst = new Date();
    let v = dst.toLocaleString('ja-JP-u-ca-japanese');
    var image = new Image();
    image.crossOrigin = "anonymous";
    image.onload = function () {
        var texture = new pc.Texture(self.app.graphicsDevice);
        texture.setSource(image);
        var material = self.entity.render.meshInstances[0].material.clone();
        self.entity.render.meshInstances[0].material = material;
        material.diffuse = new pc.Color(0, 0, 0);
        material.emissiveMap = texture;
        material.update();
    };
    image.src = `${this.url}?v=` + v;
    this.imageLoaded = true;
};

この関数が画像のロードとレンダリングの中心となります。主な処理は以下の通りです:

  1. 現在の日時をURLに付加し、キャッシュを回避します。
  2. 新しい「Image」オブジェクトを作成し、クロスオリジン設定を行います。
  3. 画像がロードされたら、新しいテクスチャを作成し、それをマテリアルに適用します。
  4. マテリアルの拡散色を黒に設定し、エミッシブマップとして新しいテクスチャを使用します。
  5. 最後に、マテリアルを更新してレンダリングを反映させます。

このスクリプトを使用することで、PlayCanvasで動的に画像をフェッチし、3Dオブジェクトにレンダリングすることができます。さらに、プレイヤーとオブジェクトの距離に基づいてロードのタイミングを制御することで、パフォーマンスの最適化も図れます。

この技術は、オンラインマルチプレイヤーゲームでのユーザーアバターの表示や、動的に変化する広告板の実装など、様々な用途に活用できます。ぜひ、皆さんのプロジェクトでも試してみてください!

Happy Coading!!

現在
株式会社チョモランマ
株式会社シェルパ
3Dmodeljapan株式会社
ではスタッフを大募集しております!!
Unreal Engine4、AI、プログラミングや建築パースに興味がある方!
ぜひご応募下さい!!
初心者の方、未経験の方やインターンを受けてみたい方々でも大歓迎です!!