Tutorials

当たり判定とトリガー

剛体が互いに衝突すると音がなります。剛体がトリガーボリュームに当たると元の場所に戻ります。

このチュートリアルでは剛体の物理、当たり判定とトリガーボリュームの基礎を紹介します。チュートリアルプロジェクトを参照してください。

コリジョンコンポーネント

コリジョン - 当たり判定コンポーネントは二つの用途に使うことができる形状を定義します。一つは他のエンティティが形状の中に入ってきたり出て行った時にイベントを発生させるトリガーボリュームと呼ばれる用途、もう一つはrigidbodyコンポーネントと組み合わせて、エンティティに弾むボールや重い箱のような物理的な性質をゲーム内で与える用途です。

コリジョンコンポーネントで最も重要なプロパティは、そのタイプです。これは使用する当たり判定の形状を決定します。全部で四種類があります:

トリガーボリューム

トリガーボリュームは、エンティティにcollisionコンポーネントを追加することで作ることができます。このチュートリアルでは大きな箱型のトリガーボリュームを坂道の下に置き、落ちてきた物体を検出して元の場所に戻すために使います。

当たり判定とトリガー

ブルーの枠線で表示されたトリガーボリュームが、坂道の下に表示されているのがわかります。

Rigid Bodies - 剛体

Rigid Body - 剛体はゲーム世界の中の物理的な存在をあらわします。重量や摩擦などの物理的な性質を設定することができ、自分以外の剛体を衝突したとき、現実的な反応をします。

剛体をシーン内に作るには、エンティティを選択してrigidbodyコンポーネントとcollisionコンポーネントを追加してください。デフォルトではstatic boxが作られます。rigidbodyコンポーネントは物体の性質を調整するために様々な設定を行うことができます。

rigidbodyコンポーネント

各プロパティの詳細はrigidbody ドキュメントをご確認ください。

このデモで重要なプロパティはTypeです。以下の三種類があります。

地面の設定

チュートリアルのはじめの一歩として、地面となる緑色のブロックを作ります。

地面をあらわすエンティティ

属性パネル内にmodelcollisionrigidbodyコンポーネントがあるのがわかります。ここではエンティティとcollisionボックスのプロパティを変更し、十分に大きな箱にしています。また、摩擦と反射係数を少し増やしています。これにより、デフォルトの値より箱の表面は少し粗く、また弾みやすくなります。

トリガーの設定

次にトリガーとなるエンティティを作成します。

トリガーエンティティ

このエンティティはcollisionコンポーネントはありますが、rigidbodyコンポーネントはありません。そのためこのエンティティはトリガーとして振る舞います。このトリガーエンティティにはコードが書き込まれたscriptコンポーネントが与えられています。トリガーは発生した時に何らかの処理を行った時はじめて意味があるものになります。そのため、処理を行うコードとトリガーが発生した際のイベントを監視するコードを追加する必要があります。

var Trigger = pc.createScript('trigger');

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

Trigger.prototype.onTriggerEnter = function(entity) {
    entity.rigidbody.linearVelocity = pc.Vec3.ZERO;
    entity.rigidbody.angularVelocity = pc.Vec3.ZERO;
    // Reset back to roughly the position the entity started in.
    var position = entity.getPosition();
    entity.rigidbody.teleport(position.x, 10, 0);
};

上記のコードには大きく分けて二つの機能があります。

まず、initializeメソッド内でtriggerenterイベントの監視を始めます。このイベントは剛体がトリガーボリューム(collisionコンポーネントのみを持ち、rigidbodyコンポーネントを持たないエンティティ)に入った時に発生します。対応する反対のイベントはtriggerleaveイベントで、これは剛体がトリガーボリュームの外に出た時に発生します。

this.entity.collision.on('triggerenter', this.onTriggerEnter, this);

三番目の引数であるthisはイベントリスナーで使われる'scope'であることに注意してください。通常は三番目の引数として、現在のスクリプトオブジェクトを与えます。これはイベントリスナー内のthisの値をイベントリスナーを設定しているスクリプトオブジェクトと同じものにするためです。

このコードの二番目の部分は、イベント処理部分のonTriggerEnter.です。トリガーが発生すると、この関数が呼び出されてトリガーボリュームに入ってくるEntityオブジェクトが渡されます。

このサンプルでトリガーが発生した場合は、トリガーボリュームに侵入したエンティティを初期位置にリセットし、同時に速度もリセットしています。

Rigid Bodies - 剛体

地面はStaticな剛体として設定します。さらに、落ちてくるオブジェクトを作成し、Dynamicとして設定します。

ボックスエンティティ

ボックスコンポーネント用のrigidbodycollision設定を行います。球とカプセルについても同様に設定します。

接触イベント

collisionコンポーネントには三種類のイベントが用意されています。

contactcollisionstartの違いはささいなことですが重要なものです。立方体が一定の角度で平面に落ちるとします。立方体の辺が平面に触ったとき、立方体の二つの頂点が同時に平面に当たります。この状態では、三つのイベントが発生します。二つのcontactイベントがそれぞれの頂点向けに発生し、さらに一つのcollisionstartイベントが発生します。そして立方体は平面上に静止するまで回転して落ち続けます。その間ずっと平面上と何らかの形で接触し続けるものとします。平面上に静止したとき、頂点が平面に触った時、さらに二つのcontactイベントが発生します。しかし、立方体は平面に触れ続けているので、collisionstartが追加で発生することはありません。

どちらのイベントも便利ですが、このデモではcollisionstartイベントを地面に触れた時の効果音を鳴らすトリガーとして使用しています。以下がコードです:

var Collider = pc.createScript('collider');

// initialize code called once per entity
Collider.prototype.initialize = function () {
    this.entity.collision.on('collisionstart', this.onCollisionStart, this);
};

Collider.prototype.onCollisionStart = function (result) {
    if (result.other.rigidbody) {
        this.entity.sound.play("hit");
    }
};

initializeメソッドでイベントリスナが設定されています。そしてイベントハンドラの中では、衝突した相手のエンティティがrigidbodyコンポーネントを持っているかを確認し(これはトリガーボリュームに入った際に効果音を鳴らさないためです)、そして"hit"サウンドエフェクトを鳴らします。このようにして、colliderスクリプトを持つエンティティが他の剛体と衝突すると、毎回衝突の効果音を鳴らしています。

これでPlayCanvasでの当たり判定とトリガーの扱い方の説明を終わります。

This site is translated by the community. If you want to get involved visit this page