Skip to content

当たり判定

物理系のモード(SimplePhysicsKinematicCharacterDynamicCharacter)のオブジェクトは、 衝突したことを検知して処理を書くことができます。

使うためには、setMode()のオプションでcollisionDetection: trueを 指定しておく必要があります(デフォルトはfalse)。衝突する 両方のオブジェクトで有効にしてください。

js
obj.setMode('SimplePhysics',{collisionDetection: true});

衝突を受け取る方法は2つあります。

ObjectA3.handleCollision()

オブジェクトのクラスを継承してhandleCollision()メソッドを 実装する方法です。「ぶつかったときにどうするか」をオブジェクト 自身に書けるので、ゲームのキャラクターやアイテムに向いています。

引数は、ぶつかった相手のオブジェクト、衝突の開始か終了か、 自分・相手のぶつかったパーツ番号の4つです。

以下はよく弾むボールを床に落とすサンプルです。バウンドのたびに 衝突の開始・終了がコンソールに表示されます。

js
import * as a3 from 'a3js';

// Sphereを継承してhandleCollision()を実装する
class MySphere extends a3.Sphere {
  handleCollision(obj, started, myPartNo, yourPartNo) {
    console.log(`衝突${started ? '開始' : '終了'}: `, obj);
  }
}

await a3.initPhysics();
const view = new a3.Window(600,300);
view.camera.setPosition(0,0,10);

const ground = new a3.Box(10,0.5,10,"red");
ground.setMode('SimplePhysics',{rigidBody:'fixed', collisionDetection:true});
ground.setPositionNow(0,-3,0);
view.scene.add(ground);

// よく弾む(restitution:0.8)ボールを落とす
const ball = new MySphere('blue');
ball.setMode('SimplePhysics',{collisionDetection:true, restitution:0.8});
ball.setPositionNow(0,3,0);
view.scene.add(ball);

相手が誰かによって処理を分けたいときは、instanceofで相手の クラスを調べるのが定番です。

js
handleCollision(obj, started, myPartNo, yourPartNo) {
  if (!started) return;         // 衝突開始のときだけ処理
  if (obj instanceof Bullet) {  // 弾丸が当たったときだけ処理
    scene.remove(this);
  }
}

実戦的な使用例はTPSのサンプルプログラムを 参照してください。

Scene.setCollisionListener()

シーンに1つのリスナーを登録して、シーン内で起きたすべての衝突を まとめて受け取る方法です。衝突の組み合わせをまとめて管理したい 場合や、クラスを作らずに書きたい場合に向いています。

js
view.scene.setCollisionListener((collisions)=>{
  for (const c of collisions) {
    console.log(c.objectA, c.objectB, c.started);
  }
});

リスナーにはそのフレームで起きた衝突(Collision)の配列が 渡されます。Collisionは以下の情報を持っています。

  • objectA/objectB — 衝突した2つのオブジェクト。
  • partOfA/partOfB — それぞれのぶつかったパーツのコライダー番号。
  • started — 衝突開始のときtrue、衝突終了のときfalse

センサー(物理的な衝突なしの検知)

collider: 'sensor'を指定すると、物理的な衝突(跳ね返り)を 起こさずに、通過したことだけを検知できます。ゴール判定や アイテムの取得に便利です。詳しくは SimplePhysicsモードカーレースサンプルプログラムを 参照してください。