1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PlayCanvasでサンディちゃんを歩かせるゲームを作るぞ☆(第6回)~他エンティティのイベントを拾う~

Posted at

こんなん作ってます。

https://playcanv.as/b/iAPwWXqY/
※本解説よりも開発が進んでいることもございますのでご了承ください。

一つのエンティティの衝突判定をUI用のエンティティに伝えるにはどうする?

例えばゴールポスト的な赤い円柱があって
スクリーンショット 2020-02-24 1.10.38.png

これに触れるとダイアログがでる。
スクリーンショット 2020-02-24 1.10.56.png

PlayCanvasは各エンティティにスクリプトを持たせてプログラミングされますが、円柱とUIは違うエンティティです。

どうやってエンティティ間でやりとりをしたらよいのでしょうか?

答えはユーザマニュアル>スクリプティング>通信にありました。
https://developer.playcanvas.com/ja/user-manual/scripting/communication/

通信ってのはなかなか聞かない表現かもしれませんが、他のエンティティのイベントを拾ってくることだと考えてください。

スクリプト間の通信には

  • スクリプト属性で参照づけられているエンティティのみから拾ってくるイベント
  • メインアプリケーション(this.app)を中央ハブとして、全てのエンティティから拾ってこれるアプリケーションイベント

の2種類があります。
どうみても後者が便利です(笑)

エンティティにサンディちゃんが衝突した際にUI部品へ衝突判定を伝えるよう、アプリケーションイベントを使ってプログラミングしていきます。

衝突判定

以下のスクリプトを作成します。

hitSandy.js
var HitSandy = pc.createScript('hitSandy');

// initialize code called once per entity
HitSandy.prototype.initialize = function() {
    this.entity.collision.on('triggerenter', this.onTriggerEnter, this);
};

// update code called every frame
HitSandy.prototype.update = function(dt) {
    
};

HitSandy.prototype.onTriggerEnter = function(entity) {
    this.app.fire('hitSandy:hit', this.entity.name, entity.name);
};

このスクリプトが適用されているエンティティの当たり判定に、何かしら剛体が衝突した際に「hitSandy:hit」というイベントを発火するようにしました。

ちなみに「hitSandy:hit」イベントを受け取った側は衝突した2つのエンティティの名前を受け取ることができます。

このスクリプトをPlayCanvasでサンディちゃんを歩かせるゲームを作るぞ☆(第4回)で作成したtemplatesディレクトリ内の「start」「goal」エンティティに適用してください。

(例)
スクリーンショット 2020-02-24 1.39.24.png

衝突判定をUIで表示する

イベントの通知を受け取るスクリプトの初期化関数でイベントの受け取りと、イベントを受けたときのイベントハンドラを作成。
今回の場合、当たり判定の衝突を検知したら「onSandyHit」関数をコールする。
衝突イベントからは衝突した2つのエンティティの名前も届いて、「onSandyHit」関数ではname1,name2の引数がそれを受け取るようになっています。

ui.js
// initialize code called once per entity
Ui.prototype.initialize = function() {
・・・
    // initializeメソッドに以下を追加
    // listen for the player:move event
    this.app.on('hitSandy:hit', this.onSandyHit);

    // remove player:move event listeners when script destroyed
    this.on('destroy', function() {
        this.app.off('hitSandy:hit', this,onSandyHit);
    });
}

//onSandyHitメソッドを新規追加
Ui.prototype.onSandyHit = function(name1,name2) {
    // 第1引数は衝突された側のエンティティの名前、第2引数は衝突したエンティティの名前
    // メッセージを作成。
    var caption = "";
    var message = "";
    if(name1=="start"){
        caption = "START";
        message = name2 + " start!!";
    }else if(name1 == "goal"){
        caption = "GOAL";
        message = name2 + " reach the goal!!";
    }

    // ダイアログにメッセージを載せる
    var disp_dialog = document.getElementsByClassName('pos_top_center')[0];
    disp_dialog.style.display = "block";
    disp_dialog.getElementsByClassName('caption')[0].innerHTML = caption;
    disp_dialog.getElementsByClassName('message')[0].innerHTML = message;

};

これでLaunchしてみましょう。

START
スクリーンショット 2020-02-24 16.26.20.png

GOAL
スクリーンショット 2020-02-24 16.27.01.png

1
0
0

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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?